Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
f912867
Re-sync protected config + workflow files to canonical (C1 drift)
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
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
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
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
ded3f4e
build-all-versions.yaml: pipe to Out-Host, not Write-Host
Chris-Wolfgang May 25, 2026
89eb640
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
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
75a460d
pr.yaml: fix Stage 2 coverage parser — greedy .* turned 100% into 0%
Chris-Wolfgang May 26, 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
13 changes: 6 additions & 7 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ indent_size = 2
[*.{yml,yaml}]
indent_size = 2

# PowerShell files inherit LF + UTF-8 (no BOM) + 4-space indent from
# the global [*] section above — no [*.ps1] override needed. The
# `charset = utf-8` setting is what prevents editors from writing a
# BOM, which together with the LF requirement keeps the
# `#!/usr/bin/env pwsh` shebang at the top of every script in scripts/
# working on Linux/macOS (CR breaks the kernel's exec lookup, and a
# leading BOM prevents shebang recognition entirely).
# PowerShell scripts inherit LF + UTF-8 (no BOM) + 4-space indent from
# the global [*] section above — no per-language override is needed.
# LF + no-BOM is required for the `#!/usr/bin/env pwsh` shebang (where
# present) on scripts under scripts/ to work on Linux/macOS — CR
# breaks the kernel's exec lookup, and a leading BOM prevents shebang
# recognition entirely.

# C# files
[*.cs]
Expand Down
27 changes: 20 additions & 7 deletions .github/workflows/build-all-versions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,20 +119,20 @@ jobs:
try {
# Attempt dotnet restore + build; failures are non-fatal because
# DocFX can still extract metadata from source files.
$slnFile = Get-ChildItem -Filter '*.sln' -ErrorAction SilentlyContinue |
$slnFile = Get-ChildItem -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension -in '.sln','.slnx' } |
Select-Object -First 1
if ($slnFile) {
Write-Host "Restoring $($slnFile.Name)..."
dotnet restore $slnFile.FullName 2>&1 | Write-Host
dotnet restore $slnFile.FullName 2>&1 | Out-Host
Write-Host "Building $($slnFile.Name)..."
dotnet build $slnFile.FullName --configuration Release --no-restore 2>&1 | Write-Host
dotnet build $slnFile.FullName --configuration Release --no-restore 2>&1 | Out-Host
}

Write-Host "Running docfx metadata..."
docfx metadata docfx_project/docfx.json 2>&1 | Write-Host
docfx metadata docfx_project/docfx.json 2>&1 | Out-Host

Write-Host "Running docfx build..."
docfx build docfx_project/docfx.json 2>&1 | Write-Host
docfx build docfx_project/docfx.json 2>&1 | Out-Host

if (Test-Path 'docfx_project/_site') {
$dest = Join-Path $outDir 'versions' $version
Expand Down Expand Up @@ -207,7 +207,7 @@ jobs:

Push-Location $latestWorkDir
try {
$slnFile = Get-ChildItem -Filter '*.sln' -ErrorAction SilentlyContinue |
$slnFile = Get-ChildItem -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension -in '.sln','.slnx' } |
Select-Object -First 1
if ($slnFile) {
Write-Host "Restoring $($slnFile.Name)..."
Expand Down Expand Up @@ -285,9 +285,22 @@ jobs:
Sort-Object -Property Major, Minor, Patch, Stable -Descending |
Select-Object -ExpandProperty Tag

# Only emit version-picker entries for tags whose docs were actually
# built and copied under $outDir/versions/<tag>/. Skipped tags (worktree
# add failed, DocFX produced no _site, etc.) would otherwise appear in
# versions.json as links to 404s on gh-pages.
$versionsDir = Join-Path $outDir 'versions'
$builtTags = if (Test-Path $versionsDir) {
Get-ChildItem -Path $versionsDir -Directory | Select-Object -ExpandProperty Name
} else { @() }

[array]$versions = @([PSCustomObject]@{ version = 'latest'; url = "${base}versions/latest/" })
foreach ($t in $orderedTags) {
$versions += [PSCustomObject]@{ version = $t; url = "${base}versions/$t/" }
if ($builtTags -contains $t) {
$versions += [PSCustomObject]@{ version = $t; url = "${base}versions/$t/" }
} else {
Write-Host "::notice::Skipping versions.json entry for $t — no built docs under versions/$t/"
}
}

$versionsJson = ConvertTo-Json -InputObject $versions -Depth 3
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/codeql.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,44 @@ jobs:
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# security-extended adds the broader security query pack on top of the
# default queries (more rules, slightly longer scans).
queries: security-extended

- name: Setup .NET
if: steps.check-csharp.outputs.has-csharp == 'true'
uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'

- name: Restore .NET workloads
if: steps.check-csharp.outputs.has-csharp == 'true'
shell: pwsh
run: |
# Skip entirely if no csproj declares a workload-bearing TFM (android/ios/
# maccatalyst/maui/tvos/tizen/browser) — netX.Y-windows TFMs use
# SDK-bundled projection assemblies, not the workload installer, so
# they're intentionally excluded. Saves ~5-15s on pure-library
# repos and removes a network-dependent failure mode.
$hasWorkloadTfm = @(Get-ChildItem -Recurse -Filter *.csproj |
Select-String -Pattern 'net\d+\.\d+-(android|ios|maccatalyst|maui|tvos|tizen|browser)' -List).Count -gt 0
if (-not $hasWorkloadTfm) {
Write-Host "No workload-bearing TFMs — skipping dotnet workload restore"
exit 0
}
$solution = Get-ChildItem -Path . -Recurse -Depth 2 -Include "*.sln", "*.slnx" | Select-Object -First 1
if ($solution) {
Write-Host "Restoring workloads for $($solution.FullName)"
dotnet workload restore "$($solution.FullName)"
} else {
Write-Host "No solution found; restoring workloads for all projects"
dotnet workload restore
}
if ($LASTEXITCODE -ne 0) {
Write-Error "dotnet workload restore failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
}

- name: Build for CodeQL Analysis
id: build
if: steps.check-csharp.outputs.has-csharp == 'true'
Expand Down
Loading
Loading