Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
01304bc
Re-sync unprotected template-tracked files to canonical (C1 drift)
Chris-Wolfgang May 22, 2026
f912867
Re-sync protected config + workflow files to canonical (C1 drift)
Chris-Wolfgang May 22, 2026
aaeb816
Fill {{PROJECT_NAME}} placeholder in CONTRIBUTING.md (Wolfgang.Etl.Ab…
Chris-Wolfgang May 22, 2026
43a8694
Propagate setup.ps1 UTF-8/newline fix from canonical
Chris-Wolfgang May 22, 2026
0f88027
Add canonical test/benchmark project config (Phase-0 files)
Chris-Wolfgang May 22, 2026
3951424
Drop tests/Directory.Build.props — hold test projects to the warning bar
Chris-Wolfgang May 22, 2026
b515f96
Hoist <Nullable>enable</Nullable> to Directory.Build.props
Chris-Wolfgang May 22, 2026
8b3a375
Scope the nullable hoist so it cannot break legacy / F# projects
Chris-Wolfgang May 22, 2026
0078d66
Enable CodeQL security-extended query pack (S1)
Chris-Wolfgang May 23, 2026
c128711
Add Stryker mutation-testing workflow (T3)
Chris-Wolfgang May 23, 2026
a45db91
Verify documentation builds before publishing release (D8)
Chris-Wolfgang May 23, 2026
c0ed898
Add github-actions ecosystem to Dependabot (CI2)
Chris-Wolfgang May 23, 2026
f79c0a1
Add CHANGELOG.md (D3)
Chris-Wolfgang May 23, 2026
121eff1
Verify previous versions preserved in docfx versions.json (D6)
Chris-Wolfgang May 23, 2026
5e8fce7
Scaffold PublicApiAnalyzers infrastructure (A1)
Chris-Wolfgang May 23, 2026
24571be
Canonical NuGet package metadata + SourceLink + symbol packages (CI3)
Chris-Wolfgang May 23, 2026
5891f7f
Publish code-coverage report to docs/coverage/ (T1)
Chris-Wolfgang May 23, 2026
ab59451
Address PR review round 2 (canonical-protected)
Chris-Wolfgang May 23, 2026
a017ed4
Address PR review round 2 (canonical-unprotected)
Chris-Wolfgang May 23, 2026
b76e710
Address PR review round 2 (t3-stryker)
Chris-Wolfgang May 23, 2026
26fa2f9
Fold T3 (stryker mutation-testing workflow) into canonical-protected
Chris-Wolfgang May 23, 2026
396c75d
Drop vestigial one-time setup scripts (post-bootstrap cleanup)
Chris-Wolfgang May 24, 2026
01adf64
Tighten <Nullable> condition to SDK-style C# projects only
Chris-Wolfgang May 24, 2026
6212a64
Add SDK-aware explanatory comment to <Nullable> property
Chris-Wolfgang May 24, 2026
62c4c26
Pin stryker.yaml's upload-artifact to v7 to match rest of fleet
Chris-Wolfgang May 24, 2026
002e929
Drop -UseBasicParsing from Invoke-WebRequest in docfx.yaml
Chris-Wolfgang May 24, 2026
e964730
Make ReportGenerator install idempotent in docfx.yaml T1 step
Chris-Wolfgang May 24, 2026
a89230d
Detect .slnx solutions in build-all-versions.yaml
Chris-Wolfgang May 25, 2026
3009757
Filter versions.json to tags whose docs were actually built
Chris-Wolfgang May 25, 2026
1362329
D6 preservation guard: only treat 404 as first deploy
Chris-Wolfgang May 25, 2026
940f80a
Disable persisted credentials in stryker.yaml checkout
Chris-Wolfgang May 25, 2026
10a0a2b
Make dotnet-stryker install idempotent in stryker.yaml
Chris-Wolfgang May 25, 2026
96f05a2
Gate dotnet workload restore on workload-bearing TFM detection
Chris-Wolfgang May 25, 2026
e7ddde3
release.yaml: explicit Out-File -Encoding utf8 + DocFX shell: pwsh
Chris-Wolfgang May 25, 2026
274c497
docfx.yaml T1 coverage: pass --settings coverlet.runsettings
Chris-Wolfgang May 25, 2026
e08c79b
Gate verify-docs-build on validate-release + pack-and-validate
Chris-Wolfgang May 25, 2026
e182e5f
Gate gh-pages root cleanup on DEPLOY_AS_LATEST=true
Chris-Wolfgang May 25, 2026
c4517ff
Drop -windows from workload-TFM detection regex
Chris-Wolfgang May 25, 2026
d495cf0
verify-docs-build: install full SDK set to match validate-release
Chris-Wolfgang May 25, 2026
f6c9864
D6 guard: skip on dry-runs (inputs.deploy_to_pages == false)
Chris-Wolfgang May 25, 2026
e81a27f
Fix invalid PowerShell in docfx.yaml SemVer prerelease comparator
Chris-Wolfgang May 25, 2026
2e6c2aa
Protected-file guard: detect deletions too (--diff-filter=AMRCD)
Chris-Wolfgang May 25, 2026
2440aae
Exclude *.Tests.Integration.* from pr.yaml test-discovery loops
Chris-Wolfgang May 25, 2026
b0e1d6c
Fail job when protected-config fetch/copy fails
Chris-Wolfgang May 25, 2026
d16d349
Gitleaks fetch: abort on transient failure, fall back only on missing…
Chris-Wolfgang May 25, 2026
5c80a35
verify-docs-build: gated dotnet workload restore before restore/build
Chris-Wolfgang May 25, 2026
502d3d4
pr.yaml: drop duplicated "configuration files from main" header bullet
Chris-Wolfgang May 25, 2026
18d6b05
Stage 3 coverage gate: skip when no coverage files were produced
Chris-Wolfgang May 25, 2026
4a5dc5d
Stage 2 coverage parse: accept extra columns + fail on zero matches
Chris-Wolfgang May 25, 2026
6918c86
dotnet test: add --no-build --no-restore in all stages
Chris-Wolfgang May 25, 2026
ba3039e
stryker.yaml: drop dead/broken configs<<EOF output
Chris-Wolfgang May 25, 2026
a6c683b
Remove duplicated NuGet metadata defaults from per-project csprojs
Chris-Wolfgang May 25, 2026
e0ed138
docfx.yaml: align D6 comment with the actual fetch source
Chris-Wolfgang May 25, 2026
969591a
Sync workload-TFM comment with regex (drop -windows mention)
Chris-Wolfgang May 25, 2026
f9d798f
docfx.yaml T1 coverage: pin to a single TFM (net10.0)
Chris-Wolfgang May 25, 2026
4d7d1d4
pr.yaml: fail (not skip) when ./tests is missing in a repo with src/
Chris-Wolfgang May 25, 2026
6f8e015
Repair pr.yaml after broken Stage 2 coverage-regex fan-out
Chris-Wolfgang May 25, 2026
e300277
CONTRIBUTING.md: correct format.ps1 and README-FORMATTING.md paths
Chris-Wolfgang May 25, 2026
5eb97ca
scripts/format.ps1: work from repo root + correct usage examples
Chris-Wolfgang May 25, 2026
515570d
CONTRIBUTING.md: correct AsyncFixer description (ConfigureAwait is MA…
Chris-Wolfgang May 25, 2026
a939501
Fix-BranchRuleset.ps1: normalize Repository before gh api calls
Chris-Wolfgang May 25, 2026
d756817
scripts/build-pr.ps1: align local checks with CI semantics
Chris-Wolfgang May 25, 2026
6528c0d
CONTRIBUTING.md: bump prerequisite SDK to 10.0 to match repo TFMs
Chris-Wolfgang May 25, 2026
d29727d
scripts/Validate-DocsDeploy.sh: rmdir mktemp path before worktree add
Chris-Wolfgang May 25, 2026
346d4b0
Setup-Labels.ps1: restore early -Repository format validation
Chris-Wolfgang May 25, 2026
ded3f4e
build-all-versions.yaml: pipe to Out-Host, not Write-Host
Chris-Wolfgang May 25, 2026
fde5e5e
scripts/build-pr.ps1: drop -UseBasicParsing from Invoke-WebRequest
Chris-Wolfgang May 25, 2026
89eb640
Remove subtree TreatWarningsAsErrors=false overrides
Chris-Wolfgang May 25, 2026
4af1ba1
Remove subtree TreatWarningsAsErrors=false overrides
Chris-Wolfgang May 25, 2026
c367093
pr.yaml: run protected-config copy loop in parent shell, not subshell
Chris-Wolfgang May 25, 2026
05d39a8
Stage 2 coverage regex: use greedy match to capture LAST percent
Chris-Wolfgang May 25, 2026
c7cb0af
Repair pr.yaml after second \$'-token corruption of Stage 2 regex
Chris-Wolfgang May 25, 2026
05bf7b9
Strip year-specific <Copyright> overrides from src csprojs
Chris-Wolfgang May 25, 2026
cafb734
Validate-DocsDeploy.sh: handle SSH remote URLs in REPO_NAME parsing
Chris-Wolfgang May 25, 2026
d160f95
build-pr.ps1: ensure .NET global-tools dir is on PATH after install
Chris-Wolfgang May 25, 2026
52b279e
D6 preservation guard: fail when newly-generated versions.json is mis…
Chris-Wolfgang May 25, 2026
19bd726
release.yaml: attach .snupkg symbol packages alongside .nupkg
Chris-Wolfgang May 25, 2026
afd407e
docfx.yaml deploy: precise exit-code handling on diff/commit/push
Chris-Wolfgang May 25, 2026
747d5a7
stryker.yaml: run BOTH root and per-test-project configs
Chris-Wolfgang May 25, 2026
33b3f26
Stage 1 (Linux) coverage parser: fail when 0 modules match
Chris-Wolfgang May 25, 2026
8c950b7
pr.yaml trusted-config-fetch: three correctness fixes
Chris-Wolfgang May 25, 2026
f8e32c7
docfx.yaml deploy: clear versions/<dir> and versions/latest before copy
Chris-Wolfgang May 25, 2026
61b476c
docfx coverage: add --no-restore to dotnet test
Chris-Wolfgang May 25, 2026
6c04fd7
D6 guard: also skip when deploy_as_latest is false (rebuild mode)
Chris-Wolfgang May 25, 2026
be81b1e
D6 guard: emit ::error:: via Write-Host so Actions parses the annotation
Chris-Wolfgang May 25, 2026
8d86f38
Stage 1 coverage parser: accept decimal percents + floor before compare
Chris-Wolfgang May 25, 2026
07729f4
scripts: repair Setup-Labels.ps1 param block + drop --paginate on rul…
Chris-Wolfgang May 26, 2026
75a460d
pr.yaml: fix Stage 2 coverage parser — greedy .* turned 100% into 0%
Chris-Wolfgang May 26, 2026
d213028
C4: drop stale <AssemblyVersion> from src csproj(s)
Chris-Wolfgang May 26, 2026
59e0f3c
Restore <AssemblyVersion>1.0.0.0</AssemblyVersion> + <FileVersion> (C…
Chris-Wolfgang May 28, 2026
d7afc9b
D8: add verify-docs-build job (canonical sync from repo-template#395)
Chris-Wolfgang May 28, 2026
d9a56be
Refine AssemblyVersion comment + use prerelease-safe FileVersion
Chris-Wolfgang May 28, 2026
5bd5646
Merge remote-tracking branch 'origin/canonical-unprotected' into vNext
Chris-Wolfgang Jun 1, 2026
8e27681
Merge remote-tracking branch 'origin/protected/d8-verify-docs-build-f…
Chris-Wolfgang Jun 1, 2026
8a90089
Merge remote-tracking branch 'origin/fix/restore-assemblyversion' int…
Chris-Wolfgang Jun 1, 2026
2de0836
v0.13.1 release prep: dup-fix + missing docs file + version bump
Chris-Wolfgang Jun 1, 2026
e6e0dc6
v0.13.1 prep: CHANGELOG entry, codeql v3→v4, missing picker assets
Chris-Wolfgang Jun 1, 2026
3204185
Merge main into vNext for v0.13.1 release prep
Chris-Wolfgang Jun 19, 2026
75ee19c
Fix RS0017: drop compiler-synthesized record members from PublicAPI b…
Chris-Wolfgang Jun 19, 2026
9c244f7
Merge branch 'main' into vNext
Chris-Wolfgang Jun 19, 2026
4334503
docs: fix README accuracy — TFM table, analyzer count, SDK prereq (#1…
Chris-Wolfgang Jun 19, 2026
328bdb0
docs: delete stale REPO-INSTRUCTIONS.md, add 8th analyzer to CONTRIBU…
Chris-Wolfgang Jun 19, 2026
1b4e261
Merge pull request #233 from Chris-Wolfgang/tier1/readme
Chris-Wolfgang Jun 19, 2026
46eef5d
Merge branch 'vNext' into tier1/markdown-audit
Chris-Wolfgang Jun 19, 2026
9eedcfa
Merge pull request #234 from Chris-Wolfgang/tier1/markdown-audit
Chris-Wolfgang Jun 19, 2026
36ccb26
docs: update CONTRIBUTING header '7 Analyzers' -> '8 Analyzers' to ma…
Chris-Wolfgang Jun 19, 2026
d9ce4c5
Merge remote-tracking branch 'origin/main' into vNext
Chris-Wolfgang Jun 19, 2026
36362ac
Merge remote-tracking branch 'origin/vNext' into tier1/markdown-audit
Chris-Wolfgang Jun 19, 2026
e0d5f5c
docs: fix XML-doc inaccuracies found in code review (#161)
Chris-Wolfgang Jun 19, 2026
a09b432
Merge pull request #235 from Chris-Wolfgang/tier1/doc-accuracy
Chris-Wolfgang Jun 19, 2026
9249bb7
Merge pull request #236 from Chris-Wolfgang/tier1/markdown-audit
Chris-Wolfgang Jun 19, 2026
47c0915
chore: finalize v0.13.1 CHANGELOG for release
Chris-Wolfgang Jun 20, 2026
e619782
Merge branch 'main' into vNext
Chris-Wolfgang Jun 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@
*.fsx text eol=lf

# Scripts
# PowerShell scripts: LF line endings in the index. Required for the
# `#!/usr/bin/env pwsh` shebang to work on Linux/macOS — the kernel
# parses CR as part of the interpreter name (looking for `pwsh\r`).
# BOM avoidance is enforced separately via `.editorconfig`
# (charset = utf-8 in the global [*] section); git attributes can
# only normalize line endings, not byte-order marks.
# Modern PowerShell 7+ handles LF on Windows transparently; Git's
# autocrlf still gives Windows users CRLF in their working tree if
# desired without forcing CRLF into the index.
# PowerShell scripts: enforce LF line endings in both the index AND
# the working tree (the explicit `eol=lf` overrides any user-level
# `core.autocrlf=true` setting that would otherwise convert to CRLF
# on checkout). BOM-free UTF-8 encoding is enforced separately by
# .editorconfig's global `charset = utf-8` — `.gitattributes` can
# normalize line endings (and control text/binary, diff, and merge
# behavior) but has no attribute for byte-order marks.
#
# LF is required for the `#!/usr/bin/env pwsh` shebang to work on
# Linux/macOS — the kernel parses CR as part of the interpreter name
# (looking for `pwsh\r`), and a UTF-8 BOM before `#!` would prevent
# shebang recognition entirely. Modern PowerShell 7+ handles LF on
# Windows transparently.
*.ps1 text eol=lf


Expand Down
76 changes: 76 additions & 0 deletions .github/ISSUE_TEMPLATE/maintenance-task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: "✨ Maintenance task"
description: "Track an actionable improvement under the Maintenance framework (security, performance, testing, cleanup, docs, API, or CI/CD)."
title: "[Maintenance] <category>: <short description>"
labels: [maintenance-task]
assignees: []
body:
- type: markdown
attributes:
value: |
## Maintenance framework sub-issue

This template creates a **`maintenance-task`** sub-issue under this repo's parent `Maintenance: <repo>` issue. The new issue will auto-appear in the cross-repo Maintenance project board (URL listed in the parent `Maintenance: <repo>` issue body).

- Pick exactly **one** category in the dropdown below. The corresponding `maintenance - <category>` label will need to be added manually after creation (issue forms don't yet support dynamic label addition).
- Fill in **Scope** (what's done & why), **Acceptance** (when do we close this?), and **Links** (PRs, scan output, related issues).
- If you're closing this issue via a PR, include `Fixes #<this-issue-number>` in the PR body so the auto-add workflow marks the project item as Done.

- type: dropdown
id: category
attributes:
label: Category
description: "Pick exactly one. After creation, also add the corresponding `maintenance - <category>` label."
options:
- "security — scans, finding fixes, dependency vulnerability audit"
- "performance — profile, benchmark, optimize, validate gains"
- "testing — coverage, integration/smoke/mutation tests, fixtures"
- "cleanup — refactor for reuse / quality / efficiency"
- "docs — XML doc coverage, README, CHANGELOG, samples"
- "API — public/internal surface audit, breaking-change vigilance"
- "CI/CD — Docker, CI workflow, build/publish pipeline"
validations:
required: true

- type: textarea
id: scope
attributes:
label: Scope
description: "What needs to be done? What's the motivation?"
placeholder: |
e.g.
- Profile the hot path in `Extractor.ExtractAsync` and identify the dominant allocations.
- Goal: reduce per-record allocations to enable streaming larger inputs.
validations:
required: true

- type: textarea
id: acceptance
attributes:
label: Acceptance criteria
description: "When do we close this issue? Concrete observable outcomes."
placeholder: |
e.g.
- Benchmark X shows <50% of current allocations.
- No regression in existing benchmark suite (>5%).
- Updated benchmark numbers committed.
validations:
required: true

- type: textarea
id: links
attributes:
label: Links
description: "Related PRs, scan output, prior issues, external references."
placeholder: |
- Related PR: #...
- Scan output: ...
- Related issue: #...
validations:
required: false

- type: markdown
attributes:
value: |
---

💡 **Tip for agents (Copilot etc.):** When opening a maintenance-task sub-issue, use this template and pick the matching category. After creation, add the `maintenance - <category>` label manually. See `.github/copilot-instructions.md` for the full Maintenance framework convention.
12 changes: 12 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

Fixes/Complete # (issue)

<!--
If this PR addresses a Maintenance framework sub-issue, link it explicitly so the
project board auto-marks the item as Done on merge:
Fixes #<maintenance-task-issue-number>
The Maintenance framework tracks ongoing improvement work (security, performance,
testing, cleanup, docs, API, CI/CD) — see the parent `Maintenance: <repo>` issue
for details.
-->


## Type of change

Please delete options that are not relevant.
Expand Down
99 changes: 99 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

### Changed

### Deprecated

### Removed

### Fixed

### Security

## [0.13.1] - 2026-06-19

Canonical maintenance round + binding-stability fix. No public API or
runtime behavior change vs v0.13.0. This release is the prerequisite
the downstream ETL family (`ETL-Test-Kit`, `ETL-Xml`, `ETL-Json`,
`ETL-FixedWidth`, `Etl-DbClient`, the in-development
`ETL-Csv`/`ETL-SqlBulkCopy`/`ETL-Transformers`) consumes by NuGet
reference — bumping it first lets each downstream pilot inherit the
canonical fixes cleanly rather than each fighting mixed-state
dependencies.

### Added

- **D8** — `verify-docs-build` job in `release.yaml` runs DocFX during
the release pipeline before the NuGet push, so a docs build failure
now blocks the package from shipping.
- **D8** — docs site version picker assets
(`docfx_project/public/version-picker.js`,
`docfx_project/versions.json`,
`docs/DOCFX-VERSION-PICKER.md`).
- **A1** — `PublicApiAnalyzers` scaffolding (analyzers activate when
`PublicAPI.Shipped.txt` / `PublicAPI.Unshipped.txt` are present
alongside the csproj).
- **CI3** — canonical NuGet package metadata: `Authors`, `Copyright`,
`RepositoryType`, SourceLink, snupkg symbol packages, deterministic
CI build flag, and `EmbedUntrackedSources` hoisted to
`Directory.Build.props`.
- **T3** — Stryker mutation-testing workflow (`stryker.yaml`).
- **T1** — coverage report published to docs site.
- **S1** — CodeQL `security-extended` query pack.
- **D6** — versions.json preservation guard on the docs deploy.

### Changed

- **C1** — fleet-wide template-drift sync: workflow files (`pr.yaml`,
`release.yaml`, `docfx.yaml`, `codeql.yaml`,
`build-all-versions.yaml`, `stryker.yaml`), `.editorconfig`,
`BannedSymbols.txt`, `Directory.Build.props`, and per-context
`tests/Directory.Build.props` consolidated to the canonical baseline.
- **Nullable** — `<Nullable>enable</Nullable>` consolidated into
`Directory.Build.props` (was per-csproj); per-project opt-out via
override still supported.
- **CI2** — Dependabot `github-actions` ecosystem added.
- **D3** — repo scripts hardened (`Setup-Labels.ps1`,
`Fix-BranchRuleset.ps1`).
- `github/codeql-action/init` and `analyze` bumped v3 → v4 (Node.js
20 → 24 deprecation).
- **Docs** — README accuracy pass: corrected the Target Frameworks
table (dropped the untargeted .NET 4.7.0 / 4.7.1 rows, added the
missing .NET Standard 2.0 row), analyzer count 7 → 8
(`Microsoft.CodeAnalysis.PublicApiAnalyzers`), and the build
prerequisite (.NET 8.0 → .NET 10.0 SDK). `CONTRIBUTING.md` analyzer
list updated to match.

### Removed

- `REPO-INSTRUCTIONS.md` — the repo-template post-setup bootstrap
checklist ("once you have completed the checklist below you can
delete this file"); setup is long complete.

### Fixed

- **Docs** — corrected stale XML-doc `<example>` references found in a
code-review pass: `LoaderBase` / `TransformerBase` examples referenced
a non-existent `MaxItemCount` (corrected to `MaximumItemCount`), and
`SystemProgressTimer` pointed at a non-existent `ManualProgressTimer`
type (corrected to a resolvable `IProgressTimer` reference).
- **C4** — restored explicit `<AssemblyVersion>1.0.0.0</AssemblyVersion>`
and added a prerelease-safe `<FileVersion>` (regex-strip property
function) to the src csproj. The original C4 fanout had dropped
these on the rationale that the hardcoded values were "stale"
relative to released package versions — but that staleness was the
correct binding-stability behaviour for libraries that ship a
`net462` TFM. Without an explicit pin, SDK-derived `AssemblyVersion`
would change on every minor/patch release, breaking .NET Framework
consumers without a binding redirect. (See DateTime-Extensions v1.3.1
for the post-mortem on what happens when this regression reaches a
release.)
19 changes: 12 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ You can contribute in several ways:

This project maintains **extremely high code quality standards** through multiple layers of static analysis and automated enforcement.

### The 7 Analyzers
### The 8 Analyzers

All code is analyzed by these tools during build:

Expand All @@ -62,9 +62,11 @@ All code is analyzed by these tools during build:
- Advanced C# pattern detection

3. **AsyncFixer**
- Detects async/await anti-patterns
- Ensures proper `ConfigureAwait()` usage
- Prevents fire-and-forget async calls
- Detects common async/await anti-patterns (AsyncFixer01–05)
- Flags missing or incorrect cancellation-token propagation
- Prevents fire-and-forget async calls (`async void` outside event handlers)
- NOTE: `ConfigureAwait()` enforcement is handled by Meziantou's
MA0004 / SonarAnalyzer S3216 / CA2007, not by AsyncFixer.

4. **Microsoft.VisualStudio.Threading.Analyzers**
- Thread safety enforcement
Expand All @@ -85,6 +87,10 @@ All code is analyzed by these tools during build:
- Security vulnerability detection
- Code smell identification

8. **Microsoft.CodeAnalysis.PublicApiAnalyzers**
- Tracks the declared public API surface (`PublicAPI.Shipped.txt` / `PublicAPI.Unshipped.txt`)
- Flags unintended additions, removals, or signature changes as breaking-change risks

### Async-First Enforcement

This library **prohibits synchronous blocking calls** via `BannedSymbols.txt`. The following APIs are **banned**:
Expand Down Expand Up @@ -145,7 +151,7 @@ var now = DateTimeOffset.UtcNow;
## Build and Test Instructions

### Prerequisites
- .NET 8.0 SDK or later
- .NET 10.0 SDK or later (required for the repo's net10.0 target; older SDKs cannot load the csproj)
- PowerShell Core (optional, for formatting scripts)

### Build the Project
Expand Down Expand Up @@ -185,7 +191,7 @@ dotnet format --verify-no-changes
pwsh ./scripts/format.ps1
```

See [README-FORMATTING.md](docs/README-FORMATTING.md) for detailed formatting rules.
See [docs/README-FORMATTING.md](docs/README-FORMATTING.md) for detailed formatting rules.

---

Expand Down Expand Up @@ -237,4 +243,3 @@ Please be respectful and considerate in all interactions. See [CODE_OF_CONDUCT.m
---

Thank you for contributing! 🎉

13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ is no new runtime behavior, no buffering, and no additional allocations per item
| Fluent Pipeline | `Pipeline.Extract(...).Transform(...).Load(...).RunAsync()` with compile-time stage typing |
| Progress Reporting | Built-in `IProgress<T>` support with configurable reporting intervals |
| Cancellation | Full `CancellationToken` support across all operations |
| Multi-TFM | Targets .NET Framework 4.6.2+, .NET Standard 2.0+, and .NET 5.0–10.0 |
| Multi-TFM | Targets .NET Framework 4.6.2–4.8.1, .NET Standard 2.0, and .NET 5.0–10.0 |
| Skip & Limit | `SkipItemCount` and `MaximumItemCount` for partial extraction/loading |
| Thread Safety | `Interlocked`-based counters for safe concurrent progress tracking |

Expand All @@ -116,15 +116,15 @@ is no new runtime behavior, no buffering, and no additional allocations per item

| Framework | Versions |
|-----------|----------|
| .Net Framework | .net 4.6.2, .net 4.7.0, .net 4.7.1, .net 4.7.2, .net 4.8, .net 4.8.1 |
| .Net Core | |
| .Net | .net 5.0, .net 6.0, .net 7.0, .net 8.0, .net 9.0, .net 10.0 |
| .NET Framework | 4.6.2, 4.7.2, 4.8, 4.8.1 |
| .NET Standard | 2.0 |
| .NET | 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 |

---

## 🔍 Code Quality & Static Analysis

This project enforces **strict code quality standards** through **7 specialized analyzers** and custom async-first rules:
This project enforces **strict code quality standards** through **8 specialized analyzers** and custom async-first rules:

### Analyzers in Use

Expand All @@ -135,6 +135,7 @@ This project enforces **strict code quality standards** through **7 specialized
5. **Microsoft.CodeAnalysis.BannedApiAnalyzers** - Prevents usage of banned synchronous APIs
6. **Meziantou.Analyzer** - Comprehensive code quality rules
7. **SonarAnalyzer.CSharp** - Industry-standard code analysis
8. **Microsoft.CodeAnalysis.PublicApiAnalyzers** - Tracks the public API surface to catch unintended breaking changes

### Async-First Enforcement

Expand All @@ -155,7 +156,7 @@ This library uses **`BannedSymbols.txt`** to prohibit synchronous APIs and enfor
## 🛠️ Building from Source

### Prerequisites
- [.NET 8.0 SDK](https://dotnet.microsoft.com/download) or later
- [.NET 10.0 SDK](https://dotnet.microsoft.com/download) or later (required to build all target frameworks)
- Optional: [PowerShell Core](https://github.com/PowerShell/PowerShell) for formatting scripts

### Build Steps
Expand Down
Loading
Loading