Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a4fcc45
Add pinned coverage collector
masarray Jul 12, 2026
25abab6
Enable cross-platform test coverage collection
masarray Jul 12, 2026
67f6a4f
Add deterministic coverage quality gate
masarray Jul 12, 2026
a53970b
Fix coverage test argument assembly
masarray Jul 12, 2026
89528e1
Add deterministic CycloneDX SBOM generator
masarray Jul 12, 2026
8cb189b
Fail CI and release builds on compiler warnings
masarray Jul 12, 2026
3d27337
Add coverage evidence and warning gates to CI
masarray Jul 12, 2026
9d3e190
Enforce warning-free test compilation
masarray Jul 12, 2026
06b4a2b
Require warning-free CodeQL build
masarray Jul 12, 2026
7cdb630
Add SBOM, pinned installer tool, and release attestations
masarray Jul 12, 2026
4757885
Document SBOM, provenance, and coverage gates
masarray Jul 12, 2026
d0e077c
Document coverage, SBOM, and release provenance
masarray Jul 12, 2026
413e69e
Record coverage, SBOM, and provenance hardening
masarray Jul 12, 2026
0dc2641
Expand public release verification checklist
masarray Jul 12, 2026
705fe20
Measure linked engine source in test assembly
masarray Jul 12, 2026
a3e0da9
Add explicit Coverlet runsettings
masarray Jul 12, 2026
b0eb794
Use explicit coverage runsettings
masarray Jul 12, 2026
52925cb
Use Coverlet MSBuild instrumentation
masarray Jul 12, 2026
59f3a3b
Use Coverlet MSBuild instrumentation
masarray Jul 12, 2026
3f0a05c
Collect coverage through MSBuild instrumentation
masarray Jul 12, 2026
15eccaa
Remove unused collector runsettings
masarray Jul 12, 2026
5a70ac1
Keep exact Inno package pin without brittle file metadata gate
masarray Jul 12, 2026
cd86d58
Force linked engine test assembly instrumentation
masarray Jul 12, 2026
e0e2e69
Raise verified coverage regression floor to 50 percent
masarray Jul 12, 2026
44d6ce9
Enforce 50 percent line coverage floor
masarray Jul 12, 2026
62d4e85
Document verified 50 percent coverage floor
masarray Jul 12, 2026
3e52fa9
Limit SBOM to shipped applications and stabilize output
masarray Jul 12, 2026
ceb5f3c
Document verified coverage and application-only SBOM
masarray Jul 12, 2026
f3dbe9f
Record verified coverage and application-only SBOM
masarray Jul 12, 2026
18f9455
Reject test-only packages from release SBOM
masarray Jul 12, 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: 16 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,24 @@ jobs:
- name: Restore tests
run: dotnet restore tests/ARSVIN.Tests/ARSVIN.Tests.csproj

- name: Build Publisher
run: dotnet build src/ARSVIN/ARSVIN.csproj -c Release --no-restore
- name: Build Publisher with warnings as errors
run: dotnet build src/ARSVIN/ARSVIN.csproj -c Release --no-restore -warnaserror

- name: Build Subscriber
run: dotnet build src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -c Release --no-restore
- name: Build Subscriber with warnings as errors
run: dotnet build src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -c Release --no-restore -warnaserror

- name: Test
run: dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release --no-restore --logger trx
- name: Test with coverage gate
shell: pwsh
run: .\scripts\test-with-coverage.ps1 -MinimumLineCoverage 50 -NoRestore

- name: Upload test and coverage evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: arsvin-test-evidence
path: artifacts/test-results
if-no-files-found: warn
retention-days: 14

- name: Publisher dependency vulnerability report
run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
- name: Restore solution
run: dotnet restore ARSVIN.sln

- name: Build solution
run: dotnet build ARSVIN.sln -c Release --no-restore
- name: Build solution with warnings as errors
run: dotnet build ARSVIN.sln -c Release --no-restore -warnaserror

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4
68 changes: 62 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- '.github/workflows/release.yml'
- 'installer/**'
- 'scripts/publish-release.ps1'
- 'scripts/generate-sbom.ps1'
- 'publish-win-x64.ps1'
- 'build.ps1'
- 'src/**'
Expand All @@ -35,6 +36,7 @@ concurrency:
env:
DOTNET_CLI_TELEMETRY_OPTOUT: '1'
DOTNET_NOLOGO: '1'
INNO_SETUP_VERSION: '6.7.1'

jobs:
package:
Expand Down Expand Up @@ -106,17 +108,30 @@ jobs:
throw "Tag ${{ github.ref_name }} does not point to a commit contained in main. Merge the release commit before tagging."
}

- name: Build and test
- name: Build and test with warnings as errors
shell: pwsh
run: .\build.ps1

- name: Publish single-file portable applications
shell: pwsh
run: .\scripts\publish-release.ps1 -Version '${{ steps.version.outputs.value }}' -SkipTests

- name: Install Inno Setup
- name: Install pinned Inno Setup
shell: pwsh
run: choco install innosetup --no-progress -y
run: |
choco install innosetup --version=$env:INNO_SETUP_VERSION --allow-downgrade --no-progress -y
if ($LASTEXITCODE -ne 0) {
throw "Chocolatey could not install Inno Setup $env:INNO_SETUP_VERSION."
}

$installed = choco list --local-only --exact innosetup --limit-output
if ($LASTEXITCODE -ne 0) {
throw 'Could not query the installed Inno Setup package.'
}

if ($installed -notcontains "innosetup|$env:INNO_SETUP_VERSION") {
throw "Expected Inno Setup $env:INNO_SETUP_VERSION, found: $($installed -join ', ')"
}

- name: Build Windows installer
shell: pwsh
Expand All @@ -130,6 +145,12 @@ jobs:
throw 'Inno Setup compiler (ISCC.exe) was not found.'
}

$versionInfo = (Get-Item $iscc).VersionInfo
Write-Host "Validated Chocolatey package: innosetup|$env:INNO_SETUP_VERSION"
Write-Host "ISCC path: $iscc"
Write-Host "ISCC product version metadata: $($versionInfo.ProductVersion)"
Write-Host "ISCC file version metadata: $($versionInfo.FileVersion)"

$sourceDir = (Resolve-Path '.\artifacts\installer-input').Path
$outputDir = (Resolve-Path '.\artifacts\release').Path
$version = '${{ steps.version.outputs.value }}'
Expand All @@ -144,6 +165,10 @@ jobs:
throw "Inno Setup failed with exit code $LASTEXITCODE."
}

- name: Generate CycloneDX SBOM
shell: pwsh
run: .\scripts\generate-sbom.ps1 -Version '${{ steps.version.outputs.value }}'

- name: Validate release artifacts
shell: pwsh
run: |
Expand All @@ -152,7 +177,8 @@ jobs:
'ARSVIN-Publisher-win-x64.exe',
'ArSubsv-Subscriber-win-x64.exe',
'ARSVIN-Suite-Setup-win-x64.exe',
'ARSVIN-win-x64-portable.zip'
'ARSVIN-win-x64-portable.zip',
'ARSVIN-SBOM.cdx.json'
)

foreach ($name in $expected) {
Expand All @@ -166,6 +192,14 @@ jobs:
}
}

$sbom = Get-Content (Join-Path $releaseRoot 'ARSVIN-SBOM.cdx.json') -Raw | ConvertFrom-Json
if ($sbom.bomFormat -ne 'CycloneDX' -or $sbom.specVersion -ne '1.5') {
throw 'Generated SBOM is not CycloneDX 1.5.'
}
if (@($sbom.components).Count -lt 1) {
throw 'Generated SBOM contains no dependency components.'
}

Get-ChildItem $releaseRoot -File |
Select-Object Name, Length |
Sort-Object Name |
Expand Down Expand Up @@ -259,8 +293,8 @@ jobs:
[System.Text.UTF8Encoding]::new($false)
)

if ($lines.Count -ne 4) {
throw "Expected four checksummed release artifacts, found $($lines.Count)."
if ($lines.Count -ne 5) {
throw "Expected five checksummed release artifacts, found $($lines.Count)."
}

Get-Content (Join-Path $releaseRoot 'SHA256SUMS.txt')
Expand All @@ -272,6 +306,7 @@ jobs:
path: |
artifacts/release/*.exe
artifacts/release/*.zip
artifacts/release/*.json
artifacts/release/SHA256SUMS.txt
if-no-files-found: error
retention-days: 30
Expand All @@ -283,6 +318,9 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
attestations: write
artifact-metadata: write

steps:
- name: Download validated release artifact
Expand All @@ -291,6 +329,23 @@ jobs:
name: ${{ needs.package.outputs.artifact_name }}
path: artifacts/release

- name: Attest release build provenance
uses: actions/attest@a1948c3f048ba23858d222213b7c278aabede763 # v4
with:
subject-path: |
artifacts/release/*.exe
artifacts/release/*.zip
artifacts/release/*.json
artifacts/release/SHA256SUMS.txt

- name: Attest release SBOM
uses: actions/attest@a1948c3f048ba23858d222213b7c278aabede763 # v4
with:
subject-path: |
artifacts/release/*.exe
artifacts/release/*.zip
sbom-path: artifacts/release/ARSVIN-SBOM.cdx.json

- name: Create GitHub Release
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with:
Expand All @@ -306,4 +361,5 @@ jobs:
artifacts/release/ArSubsv-Subscriber-win-x64.exe
artifacts/release/ARSVIN-Suite-Setup-win-x64.exe
artifacts/release/ARSVIN-win-x64-portable.zip
artifacts/release/ARSVIN-SBOM.cdx.json
artifacts/release/SHA256SUMS.txt
16 changes: 13 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,27 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change

## Unreleased

### Added

- Added pinned Coverlet MSBuild instrumentation, TRX/Cobertura/log evidence upload, and a verified 50% line-coverage regression floor for the linked production engine surface.
- Established a measured baseline of 57.85% line coverage across 1,535 instrumented production lines, with 888 lines covered and all 26 tests passing.
- Added a repository-owned CycloneDX 1.5 SBOM generator for direct and transitive Publisher/Subscriber NuGet dependencies while excluding test-only packages.
- Added `ARSVIN-SBOM.cdx.json` to validated workflow artifacts, release downloads, and SHA-256 checksums.
- Added signed GitHub build-provenance and SBOM attestations for tagged release artifacts.

### Security

- Pinned all GitHub Actions used by CI, CodeQL, Pages, and release workflows to immutable commit SHAs while retaining version comments for maintainability and Dependabot updates.
- Pinned automated installer compilation to the exact Inno Setup 6.7.1 Chocolatey package and retain resolved compiler metadata in workflow evidence.
- Treat compiler warnings as errors in validated Publisher, Subscriber, test, release, and CodeQL build paths.
- Stabilized SBOM component ordering, source commit, and metadata timestamp for repeatable review from the same commit.

### Planned

- Exact-version and integrity pinning for installer tooling.
- Shared `ARSVIN.Engine` class library extraction.
- Code coverage and analyzer quality gates.
- Higher coverage thresholds and expanded protocol regression tests.
- Search-indexable HTML engineering documentation.
- SBOM and release provenance/attestation.
- Windows Authenticode signing when a trusted certificate becomes available.

## 0.3.0 — 2026-07-11

Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
</ItemGroup>
</Project>
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,15 @@ Every tagged release builds validated Windows x64 artifacts with stable filename
| `ArSubsv-Subscriber-win-x64.exe` | Self-contained, single-file portable Subscriber. |
| `ARSVIN-Suite-Setup-win-x64.exe` | Installer containing both applications, Start Menu shortcuts, documentation, and uninstaller. |
| `ARSVIN-win-x64-portable.zip` | Portable suite folder containing both applications and essential documentation. |
| `ARSVIN-SBOM.cdx.json` | CycloneDX 1.5 software bill of materials for resolved NuGet dependencies. |
| `SHA256SUMS.txt` | SHA-256 checksums for release verification. |

Stable and prerelease tag builds publish signed GitHub artifact attestations for provenance. Verify a downloaded file with GitHub CLI:

```powershell
gh attestation verify .\ARSVIN-Suite-Setup-win-x64.exe --repo masarray/arsvin
```

The binaries are currently **unsigned**. Windows SmartScreen may show an unknown-publisher warning. Releases do not silently install Npcap; download Npcap from its official website when live capture or transmission is required.

## Quick start
Expand Down Expand Up @@ -121,7 +128,7 @@ For developers:
- .NET 8 SDK.
- PowerShell 7+ recommended.
- Visual Studio 2022, JetBrains Rider, or VS Code with C# tooling.
- Inno Setup 6 only when building the installer locally.
- Inno Setup 6.7.1 when reproducing the automated installer build locally.

## Build from source

Expand All @@ -134,19 +141,27 @@ cd arsvin
Build all release artifacts except the installer:

```powershell
.\scripts\publish-release.ps1 -Version 0.1.0
.\scripts\publish-release.ps1 -Version 0.3.0
```

Compatibility wrapper:

```powershell
.\publish-win-x64.ps1 -Version 0.1.0
.\publish-win-x64.ps1 -Version 0.3.0
```

Run tests directly:
Run tests with the repository coverage gate and retain TRX/Cobertura evidence:

```powershell
.\scripts\test-with-coverage.ps1 -MinimumLineCoverage 50
```

The current linked engine surface measures 57.85% line coverage across 1,535 instrumented production lines. CI enforces a 50% regression floor while the shared engine project and broader protocol tests are developed.

Generate a CycloneDX SBOM after restoring the solution:

```powershell
dotnet test .\tests\ARSVIN.Tests\ARSVIN.Tests.csproj -c Release
.\scripts\generate-sbom.ps1 -Version 0.3.0
```

## Repository structure
Expand All @@ -156,7 +171,7 @@ src/ARSVIN/ Publisher application and SV generation engine
src/ARSVIN.Subscriber/ ArSubsv subscriber and visualization companion
tests/ARSVIN.Tests/ Protocol and publisher helper tests
installer/ Inno Setup definition for the Windows suite
scripts/ Repeatable release packaging scripts
scripts/ Repeatable release packaging and validation scripts
docs/ Engineering, safety, and contributor documentation
samples/ SCL, COMTRADE, scenario, and evidence samples
site/ Static, SEO-ready GitHub Pages product site
Expand Down
6 changes: 3 additions & 3 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ Invoke-DotNet -Arguments @('restore', $subscriberProject)
Invoke-DotNet -Arguments @('restore', $testProject)

Write-Host '==> Building ARSVIN Publisher'
Invoke-DotNet -Arguments @('build', $appProject, '-c', 'Release', '--no-restore')
Invoke-DotNet -Arguments @('build', $appProject, '-c', 'Release', '--no-restore', '-warnaserror')

Write-Host '==> Building ArSubsv Subscriber'
Invoke-DotNet -Arguments @('build', $subscriberProject, '-c', 'Release', '--no-restore')
Invoke-DotNet -Arguments @('build', $subscriberProject, '-c', 'Release', '--no-restore', '-warnaserror')

Write-Host '==> Running tests'
Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore')
Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore', '/p:TreatWarningsAsErrors=true')

Write-Host '==> Build completed successfully'
Loading
Loading