diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ac4f70..6504455 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ permissions: jobs: build-test: name: Build, test, and validate site - runs-on: windows-latest + runs-on: windows-2025 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 @@ -54,9 +54,9 @@ jobs: - name: Build Subscriber with warnings as errors run: dotnet build src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -c Release --no-restore -warnaserror - - name: Test with coverage gate + - name: Test with whole-engine and protocol-core coverage gates shell: pwsh - run: .\scripts\test-with-coverage.ps1 -MinimumLineCoverage 50 -NoRestore + run: .\scripts\test-with-coverage.ps1 -MinimumWholeEngineLineCoverage 5.5 -MinimumLineCoverage 50 -NoRestore - name: Upload test and coverage evidence if: always() diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8c4996e..ec25ceb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -15,7 +15,7 @@ permissions: jobs: analyze: name: Analyze C# solution - runs-on: windows-latest + runs-on: windows-2025 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 099c23b..2b1de49 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -8,6 +8,7 @@ on: - 'docs/**' - 'scripts/build-public-site.py' - 'scripts/validate-public-site.ps1' + - 'scripts/validate-public-site.py' - '.github/workflows/pages.yml' workflow_dispatch: @@ -25,7 +26,7 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4e46619..ceb63bf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,7 +41,7 @@ env: jobs: package: name: Validate portable EXEs and installer - runs-on: windows-latest + runs-on: windows-2025 outputs: version: ${{ steps.version.outputs.value }} tag_name: ${{ steps.version.outputs.tag_name }} @@ -60,8 +60,9 @@ jobs: dotnet-version: 8.0.4xx cache: true cache-dependency-path: | - **/*.csproj Directory.Packages.props + src/**/packages.lock.json + tests/**/packages.lock.json - name: Resolve version id: version @@ -327,7 +328,7 @@ jobs: name: Publish GitHub Release if: github.ref_type == 'tag' needs: package - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 permissions: contents: write id-token: write diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e7bc9e..354abd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change - Added recursive validation for all HTML metadata, structured data, canonical uniqueness, local references, search-index targets, sitemap coverage, web-manifest icons, and robots metadata. - Added committed NuGet lock files for Publisher, Subscriber, the shared engine, and Tests. - Added CI evidence upload for the committed dependency lock graph. +- Added a 5.5% whole-engine line-coverage regression floor alongside the existing 50% protocol-core floor. ### Changed @@ -20,11 +21,14 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change - The product landing page now links directly to Quick Start, SV Profile Support, COMTRADE Replay, Subscriber Verification, Safety Boundaries, and the complete documentation index. - Validated CI, CodeQL, build, test, publish, and release paths now restore NuGet dependencies in locked mode. - README, build guidance, contributor guidance, repository structure, release examples, and coverage baselines now match the current shared-engine implementation. +- CI, CodeQL, and release validation now use the explicit `windows-2025` runner image; Pages and release publication use `ubuntu-24.04`. +- GitHub Pages now retriggers when the Python public-site validator changes. ### Security - Published GitHub Releases are now immutable in automation; a release job fails before attestation or upload when the semantic-version tag already has a GitHub Release. - Artifact corrections require a new semantic-version patch instead of replacing previously published binaries, checksums, or SBOMs. +- Workflow execution no longer depends on moving `windows-latest` or `ubuntu-latest` labels. ### Planned diff --git a/scripts/test-with-coverage.ps1 b/scripts/test-with-coverage.ps1 index 727dbbb..b3608b7 100644 --- a/scripts/test-with-coverage.ps1 +++ b/scripts/test-with-coverage.ps1 @@ -3,6 +3,9 @@ param( [ValidateRange(0, 100)] [double] $MinimumLineCoverage = 50, + [ValidateRange(0, 100)] + [double] $MinimumWholeEngineLineCoverage = 5.5, + [switch] $NoRestore ) @@ -30,9 +33,8 @@ if ($NoRestore) { $arguments += '--no-restore' } -# Instrument the complete production engine. The report remains a truthful -# whole-engine baseline, while the regression gate below is calculated over -# the protocol-core surface that has an established test baseline. +# Instrument the complete production engine. CI now protects both the truthful +# whole-engine baseline and the higher protocol-core regression baseline. $arguments += @( '/p:RestoreLockedMode=true', '/p:TreatWarningsAsErrors=true', @@ -130,6 +132,7 @@ $coreLineCoverage = [Math]::Round(($coreLinesCovered / $coreLinesValid) * 100, 2 Write-Host "Whole engine lines: $overallLinesValid" Write-Host "Whole engine line coverage: $overallLineCoverage%" +Write-Host "Whole engine minimum required: $MinimumWholeEngineLineCoverage%" Write-Host "Protocol core files: $($coreFiles.Count)" Write-Host "Protocol core lines: $coreLinesValid" Write-Host "Protocol core covered lines: $coreLinesCovered" @@ -145,6 +148,7 @@ if ($env:GITHUB_STEP_SUMMARY) { |---|---:| | Whole `ARSVIN.Engine` instrumented lines | **$overallLinesValid** | | Whole engine line coverage | **$overallLineCoverage%** | +| Whole-engine regression floor | **$MinimumWholeEngineLineCoverage%** | | Tested protocol-core files | **$($coreFiles.Count)** | | Protocol-core instrumented lines | **$coreLinesValid** | | Protocol-core covered lines | **$coreLinesCovered** | @@ -154,6 +158,14 @@ if ($env:GITHUB_STEP_SUMMARY) { "@ | Add-Content $env:GITHUB_STEP_SUMMARY } +$coverageFailures = [System.Collections.Generic.List[string]]::new() +if ($overallLineCoverage -lt $MinimumWholeEngineLineCoverage) { + $coverageFailures.Add("Whole-engine line coverage $overallLineCoverage% is below the required $MinimumWholeEngineLineCoverage%.") +} if ($coreLineCoverage -lt $MinimumLineCoverage) { - throw "Protocol-core line coverage $coreLineCoverage% is below the required $MinimumLineCoverage%." + $coverageFailures.Add("Protocol-core line coverage $coreLineCoverage% is below the required $MinimumLineCoverage%.") +} + +if ($coverageFailures.Count -gt 0) { + throw ($coverageFailures -join ' ') }