From 23b3845f2afde583f6e33369874c7b7b2e971a72 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:02:16 +0700 Subject: [PATCH 01/25] Enable NuGet dependency lock files --- Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Build.props b/Directory.Build.props index 3091879..63164ad 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,6 +6,7 @@ false true true + true 0.3.1 https://github.com/masarray/arsvin git From 05c0a693f83c2cd8352d9fe431658091819683ea Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:02:38 +0700 Subject: [PATCH 02/25] Generate and retain NuGet dependency lock files in CI --- .github/workflows/ci.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7bd294..3e7f78e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,14 +30,18 @@ jobs: shell: pwsh run: .\scripts\validate-public-site.ps1 -SiteRoot artifacts/public-site - - name: Restore Publisher - run: dotnet restore src/ARSVIN/ARSVIN.csproj + - name: Restore solution and generate NuGet lock files + run: dotnet restore ARSVIN.sln --use-lock-file - - name: Restore Subscriber - run: dotnet restore src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj - - - name: Restore tests - run: dotnet restore tests/ARSVIN.Tests/ARSVIN.Tests.csproj + - name: Upload generated NuGet lock files + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: arsvin-nuget-lockfiles + path: | + src/**/packages.lock.json + tests/**/packages.lock.json + if-no-files-found: error + retention-days: 7 - name: Build Publisher with warnings as errors run: dotnet build src/ARSVIN/ARSVIN.csproj -c Release --no-restore -warnaserror From 4a3c5dac15265c38c3af4001223781a01421a065 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:03:52 +0700 Subject: [PATCH 03/25] Prevent published GitHub releases from being overwritten --- .github/workflows/release.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 83d684e..4e46619 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -341,6 +341,28 @@ jobs: name: ${{ needs.package.outputs.artifact_name }} path: artifacts/release + - name: Refuse to overwrite an existing GitHub Release + env: + GH_TOKEN: ${{ github.token }} + RELEASE_TAG: ${{ needs.package.outputs.tag_name }} + shell: bash + run: | + set -euo pipefail + endpoint="repos/${GITHUB_REPOSITORY}/releases/tags/${RELEASE_TAG}" + + if existing_release="$(gh api "$endpoint" 2>&1)"; then + echo "::error::GitHub Release ${RELEASE_TAG} already exists. Published releases are immutable; create a new semantic-version tag instead." + exit 1 + fi + + if ! grep -q 'HTTP 404' <<<"$existing_release"; then + echo "$existing_release" >&2 + echo "::error::Could not verify whether GitHub Release ${RELEASE_TAG} already exists." + exit 1 + fi + + echo "No existing GitHub Release found for ${RELEASE_TAG}; publication may continue." + - name: Attest release build provenance uses: actions/attest@a1948c3f048ba23858d222213b7c278aabede763 # v4 with: From e1c0ccd6bc4b4c6350fb0b7244d1fdacf481421d Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:04:42 +0700 Subject: [PATCH 04/25] Synchronize public documentation with the current engine and release controls --- README.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b07a375..b0de73e 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,8 @@ Stable and prerelease tag builds publish signed GitHub artifact attestations for gh attestation verify .\ARSVIN-Suite-Setup-win-x64.exe --repo masarray/arsvin ``` +Published GitHub Releases are immutable in the automated workflow. Corrections use a new semantic-version tag instead of replacing existing assets. + 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 @@ -125,7 +127,7 @@ For users: For developers: -- .NET 8 SDK. +- .NET 8 SDK, feature band 8.0.4xx. - PowerShell 7+ recommended. - Visual Studio 2022, JetBrains Rider, or VS Code with C# tooling. - Inno Setup 6.7.1 when reproducing the automated installer build locally. @@ -138,16 +140,18 @@ cd arsvin .\build.ps1 ``` +NuGet versions are centrally managed and committed `packages.lock.json` files lock the resolved dependency graph. Validated CI and release paths restore with `--locked-mode`. + Build all release artifacts except the installer: ```powershell -.\scripts\publish-release.ps1 -Version 0.3.0 +.\scripts\publish-release.ps1 -Version 0.3.1 ``` Compatibility wrapper: ```powershell -.\publish-win-x64.ps1 -Version 0.3.0 +.\publish-win-x64.ps1 -Version 0.3.1 ``` Run tests with the repository coverage gate and retain TRX/Cobertura evidence: @@ -156,18 +160,19 @@ Run tests with the repository coverage gate and retain TRX/Cobertura evidence: .\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. +The complete shared `ARSVIN.Engine` baseline currently measures 5.64% line coverage across 15,726 instrumented production lines. The established protocol-core regression surface measures 57.89% across 1,534 lines, with 888 covered lines; CI enforces a 50% floor on that tested protocol-core surface while broader engine tests are added. Generate a CycloneDX SBOM after restoring the solution: ```powershell -.\scripts\generate-sbom.ps1 -Version 0.3.0 +.\scripts\generate-sbom.ps1 -Version 0.3.1 ``` ## Repository structure ```text -src/ARSVIN/ Publisher application and SV generation engine +src/ARSVIN.Engine/ Shared IEC 61850 protocol, SCL, capture, transport, and SV engine project +src/ARSVIN/ Publisher application src/ARSVIN.Subscriber/ ArSubsv subscriber and visualization companion tests/ARSVIN.Tests/ Protocol and publisher helper tests installer/ Inno Setup definition for the Windows suite @@ -178,6 +183,8 @@ site/ Static, SEO-ready GitHub Pages product site .github/workflows/ CI, CodeQL, Pages, and release automation ``` +The shared engine is compiled once as `ARSVIN.Engine`; its source files are still physically located under `src/ARSVIN/Engine` during the staged directory migration. + ## Documentation - [Documentation index](docs/index.md) From 4ad082266807bfa9f30990a046472b8fe869a40c Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:05:25 +0700 Subject: [PATCH 05/25] Update build and release guide for locked dependencies and immutable releases --- docs/build-and-release.md | 130 ++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 40 deletions(-) diff --git a/docs/build-and-release.md b/docs/build-and-release.md index 6c5a720..94da99e 100644 --- a/docs/build-and-release.md +++ b/docs/build-and-release.md @@ -17,14 +17,33 @@ For local installer builds: Npcap is required only for live capture/transmission testing. It is not silently bundled or installed by the ARSVIN release process. +## Dependency locking + +Package versions are centrally managed in `Directory.Packages.props`. Each project also commits a `packages.lock.json` file so the resolved direct and transitive NuGet graph is reviewable and repeatable. + +Validated automation restores with locked mode: + +```powershell +dotnet restore ARSVIN.sln --locked-mode +``` + +A dependency update must intentionally regenerate the affected lock files and include them in the same pull request: + +```powershell +dotnet restore ARSVIN.sln --force-evaluate +``` + +Do not hand-edit lock files. Review dependency and integrity changes in the generated diff. + ## Build and test ```powershell .\build.ps1 ``` -The script restores, builds, and tests: +The script restores the solution in locked mode, then builds and tests: +- `src/ARSVIN.Engine/ARSVIN.Engine.csproj` - `src/ARSVIN/ARSVIN.csproj` - `src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj` - `tests/ARSVIN.Tests/ARSVIN.Tests.csproj` @@ -40,33 +59,64 @@ External command exit codes are checked, and compiler warnings are treated as er The script: 1. runs the xUnit suite using pinned Coverlet MSBuild instrumentation, -2. explicitly instruments the linked production engine source in `ARSVIN.Tests`, -3. excludes test and generated source files from the reported metric, -4. writes TRX, the complete `dotnet test` log, and Cobertura evidence under `artifacts/test-results`, -5. fails when no production lines are instrumented or line coverage is below the configured threshold. +2. instruments the complete shared production `ARSVIN.Engine` assembly, +3. writes TRX, the complete `dotnet test` log, and Cobertura evidence under `artifacts/test-results`, +4. reports whole-engine coverage transparently, +5. calculates the regression gate over the established protocol-core surface, +6. fails when no production lines are instrumented or protocol-core coverage falls below the configured threshold. -The verified baseline is 57.85% line coverage over 1,535 instrumented production lines, with 888 lines covered. CI enforces a 50% regression floor. This is not a claim that the complete WPF UI or every live-network path is covered; raise the threshold as the shared engine project and protocol tests expand. +Current verified baselines: + +| Metric | Result | +|---|---:| +| Whole `ARSVIN.Engine` instrumented lines | 15,726 | +| Whole-engine line coverage | 5.64% | +| Protocol-core instrumented lines | 1,534 | +| Protocol-core covered lines | 888 | +| Protocol-core line coverage | 57.89% | +| Enforced protocol-core floor | 50% | + +This is not a claim that the complete WPF UI or every live-network path is covered. Whole-engine coverage is intentionally shown as a transparent baseline and must rise as SCL, COMTRADE, capture, diagnostics, MMS, scheduling, and transport tests are expanded. ## Validate the public site +Build the staged landing page and HTML documentation: + ```powershell -.\scripts\validate-public-site.ps1 +python scripts/build-public-site.py --output artifacts/public-site ``` -The validator checks required landing-page files, local asset references, JSON-LD blocks, web-manifest icons, sitemap canonical URL, release download filenames, and the sitemap reference in `robots.txt`. +Validate the staged output: + +```powershell +.\scripts\validate-public-site.ps1 -SiteRoot artifacts/public-site +``` -The same validator runs directly inside the GitHub Pages deployment job. A broken landing page cannot be deployed merely because a separate CI job has not finished yet. +The validator recursively checks: + +- one `

` per public page, +- descriptions and canonical URLs, +- canonical uniqueness, +- valid JSON-LD, +- local links and assets, +- documentation search-index targets, +- sitemap coverage, +- web-manifest icons, +- release filenames, +- sitemap metadata in `robots.txt`. + +The same builder and validator run directly inside GitHub Pages deployment. A broken page cannot deploy merely because a separate CI job has not finished yet. ## Build portable release artifacts ```powershell -.\scripts\publish-release.ps1 -Version 0.3.0 +.\scripts\publish-release.ps1 -Version 0.3.1 ``` Compatibility wrapper: ```powershell -.\publish-win-x64.ps1 -Version 0.3.0 +.\publish-win-x64.ps1 -Version 0.3.1 ``` Generated files: @@ -88,10 +138,10 @@ The two direct `.exe` files are self-contained .NET 8 single-file applications. ## Generate the CycloneDX SBOM -After restoring the application projects, run: +After restoring the solution, run: ```powershell -.\scripts\generate-sbom.ps1 -Version 0.3.0 +.\scripts\generate-sbom.ps1 -Version 0.3.1 ``` Output: @@ -100,16 +150,16 @@ Output: artifacts/release/ARSVIN-SBOM.cdx.json ``` -The generator reads the resolved NuGet graphs for the Publisher and Subscriber projects, deduplicates direct and transitive application packages, records which application uses each package, and writes CycloneDX 1.5 JSON. Test-only packages such as xUnit and Coverlet are intentionally excluded from the release SBOM. +The generator reads the locked, resolved NuGet graphs for Publisher and Subscriber, deduplicates direct and transitive application packages, records which application uses each package, and writes CycloneDX 1.5 JSON. Test-only packages such as xUnit and Coverlet are intentionally excluded. -Component order and metadata timestamp are stabilized from the source commit so repeated generation from the same commit and version is reviewable. The SBOM covers managed application dependencies; it does not claim to inventory Windows, Npcap, GitHub-hosted runner contents, or every tool used by the build service. +The SBOM includes a deterministic UUID URN `serialNumber`, source commit metadata, component version, and stable component ordering. Repeated generation from the same commit and version is reviewable. The SBOM covers managed application dependencies; it does not claim to inventory Windows, Npcap, GitHub-hosted runner contents, or every build-service tool. ## Build the installer locally After running the publish script: ```powershell -$version = '0.3.0' +$version = '0.3.1' $sourceDir = (Resolve-Path '.\artifacts\installer-input').Path $outputDir = (Resolve-Path '.\artifacts\release').Path $iscc = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" @@ -146,25 +196,26 @@ Workflow: `.github/workflows/release.yml` ### Pull-request validation -When release tooling, installer definitions, project files, or build configuration change, the workflow runs on the pull request and: - -1. restores, builds, and tests the solution with warnings treated as errors, -2. publishes both portable single-file applications, -3. creates the portable suite ZIP, -4. installs and verifies the pinned Inno Setup package, -5. compiles the installer, -6. generates and structurally validates the application-only CycloneDX SBOM, -7. checks all expected artifact names and non-empty files, -8. silently installs the suite into a temporary directory, -9. verifies Publisher, Subscriber, documentation, version file, and uninstaller, -10. silently uninstalls the temporary installation, -11. generates checksums and uploads a private workflow artifact. +When release tooling, installer definitions, project files, dependency locks, or build configuration change, the workflow runs on the pull request and: + +1. restores the locked dependency graph, +2. builds and tests the solution with warnings treated as errors, +3. publishes both portable single-file applications, +4. creates the portable suite ZIP, +5. installs and verifies pinned Inno Setup, +6. compiles the installer, +7. generates and structurally validates the application-only CycloneDX SBOM, +8. checks all expected artifact names and non-empty files, +9. silently installs the suite into a temporary directory, +10. verifies Publisher, Subscriber, documentation, version file, and uninstaller, +11. silently uninstalls the temporary installation, +12. generates checksums and uploads a private workflow artifact. A pull-request run never creates a public GitHub Release or public attestation. ### Stable tagged release -A public release is created only by pushing a semantic version tag. The tagged commit must already be contained in `main`; the workflow rejects a tag created from an unmerged feature or release branch. +A public release is created only by pushing a semantic-version tag. The tagged commit must already be contained in `main`; the workflow rejects a tag created from an unmerged feature or release branch. ```powershell git switch main @@ -173,7 +224,11 @@ git tag -a v0.4.0 -m "ARSVIN v0.4.0" git push origin v0.4.0 ``` -The workflow repeats the validated packaging path, downloads the validated workflow artifact in a separate least-privilege release job, creates signed provenance and SBOM attestations, and publishes all public files to GitHub Releases. Stable tags are eligible to become the repository's latest release. +The workflow repeats the validated packaging path, downloads the validated artifact in a separate least-privilege release job, verifies that no GitHub Release already exists for the tag, creates signed provenance and SBOM attestations, and publishes the public files. + +Published GitHub Releases are immutable in automation. A rerun cannot replace existing assets. Any artifact correction requires a new patch version, such as `v0.4.1`. + +Stable tags are eligible to become the repository's latest release. ### Prerelease tag @@ -236,13 +291,8 @@ Before tagging a public release: - Confirm the intended release commit is already on `main`. - Confirm `main` CI, release validation, and CodeQL are green. - Update `VersionPrefix` and `CHANGELOG.md`. +- Confirm committed NuGet lock files match the reviewed dependency update. - Review the generated application SBOM and checksums. -- Test Publisher dry run. -- Test live publishing only on an isolated lab link. -- Test Subscriber live capture and PCAP import. -- Verify generated SV traffic independently in Wireshark. -- Verify portable executables on a clean Windows 10/11 x64 machine. -- Verify install, upgrade, shortcuts, launch, and uninstall behavior. -- Review [Known Limitations](known-limitations.md). -- Review [Safety Boundaries](safety-boundaries.md). -- Review [Public Release Checklist](public-release-checklist.md). +- Confirm no GitHub Release already exists for the intended tag. +- Test Publisher dry run and Subscriber PCAP import. +- Use a new patch version for any correction to an already published release. From 7eb0cdd058d4d9a2292d6673b0555b215a7b4e36 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:05:45 +0700 Subject: [PATCH 06/25] Document locked dependency update workflow for contributors --- CONTRIBUTING.md | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e5ad2b..ac28852 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,35 +12,53 @@ ARSVIN is an engineering suite for IEC 61850 Sampled Values laboratory workflows - Preserve Apache-2.0 compatibility. - Prefer explicit engineering wording over marketing claims. - Update documentation when behavior, UI, safety assumptions, or release packaging changes. +- Preserve committed NuGet lock files and immutable public releases. ## Development setup Recommended environment: - Windows 10/11 x64 -- .NET 8 SDK +- .NET 8 SDK, feature band 8.0.4xx - PowerShell 7+ - Npcap for live packet capture/publishing tests - Wireshark for packet inspection -Build: +Build using the committed dependency graph: ```powershell .\build.ps1 ``` -Run tests: +Run tests and produce coverage evidence: ```powershell -dotnet test tests/ARSVIN.Tests/ARSVIN.Tests.csproj -c Release +.\scripts\test-with-coverage.ps1 -MinimumLineCoverage 50 ``` -Create portable release artifacts: +Create portable release artifacts for the current source version: ```powershell -.\scripts\publish-release.ps1 -Version 0.1.0 +.\scripts\publish-release.ps1 -Version 0.3.1 ``` +## Dependency updates + +NuGet versions are centrally managed in `Directory.Packages.props`, and each project commits `packages.lock.json`. + +Normal builds and automation restore with locked mode. When deliberately changing a dependency: + +1. update the version in `Directory.Packages.props`, +2. regenerate lock files from the repository root, +3. review direct and transitive changes, +4. commit package-version and lock-file changes together. + +```powershell +dotnet restore ARSVIN.sln --force-evaluate +``` + +Do not hand-edit `packages.lock.json`. Unrelated lock-file churn should not be included in a pull request. + ## Pull request checklist Before opening a PR, please check: @@ -48,10 +66,12 @@ Before opening a PR, please check: - The change has a narrow engineering purpose. - Both affected applications build in Release mode. - Relevant unit tests were added or updated where practical. +- The protocol-core coverage floor still passes, and broader coverage changes are explained. - Safety behavior is not weakened. - Docs are updated for user-visible changes. - Screenshots or Wireshark notes are included for UI / packet behavior changes. -- New dependencies are necessary, maintained, and license-compatible. +- New dependencies are necessary, maintained, license-compatible, and represented in lock files. +- Release-workflow changes preserve tag-only publication and immutable existing releases. ## Commit and branch style From fdd9397b442f7ddc25fd11636ead20c30732cca9 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:08:56 +0700 Subject: [PATCH 07/25] Commit generated NuGet lock files --- src/ARSVIN/packages.lock.json | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/ARSVIN/packages.lock.json diff --git a/src/ARSVIN/packages.lock.json b/src/ARSVIN/packages.lock.json new file mode 100644 index 0000000..c95b8dd --- /dev/null +++ b/src/ARSVIN/packages.lock.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "dependencies": { + "net8.0-windows7.0": { + "PacketDotNet": { + "type": "Transitive", + "resolved": "1.4.8", + "contentHash": "j4C4QaJmaPCk0KXsIdsZqmBteKWj5znXBmfbPpu48rE5SW2xwXKVlRf7C3g7VM9aZqMHIQedApEuC71nNX5PaQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + }, + "arsvin.engine": { + "type": "Project", + "dependencies": { + "SharpPcap": "[6.3.1, )" + } + }, + "SharpPcap": { + "type": "CentralTransitive", + "requested": "[6.3.1, )", + "resolved": "6.3.1", + "contentHash": "EWclXz+QdffBRppFR7GDBLyKiAz045RGvu4t4gcMGocVMEq6dRfCnAEx7Ep6qxcPPhH2kz13Y8FqBaHZhsh3Pg==", + "dependencies": { + "PacketDotNet": "1.4.8", + "System.Memory": "4.6.3", + "System.Text.Encoding.CodePages": "9.0.5" + } + } + } + } +} From 560a33ac32c0f41e0f532d4e001f4ebeb4c7ff3c Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:09:11 +0700 Subject: [PATCH 08/25] Commit generated engine dependency lock --- src/ARSVIN.Engine/packages.lock.json | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/ARSVIN.Engine/packages.lock.json diff --git a/src/ARSVIN.Engine/packages.lock.json b/src/ARSVIN.Engine/packages.lock.json new file mode 100644 index 0000000..89e6f1d --- /dev/null +++ b/src/ARSVIN.Engine/packages.lock.json @@ -0,0 +1,41 @@ +{ + "version": 2, + "dependencies": { + "net8.0": { + "SharpPcap": { + "type": "Direct", + "requested": "[6.3.1, )", + "resolved": "6.3.1", + "contentHash": "EWclXz+QdffBRppFR7GDBLyKiAz045RGvu4t4gcMGocVMEq6dRfCnAEx7Ep6qxcPPhH2kz13Y8FqBaHZhsh3Pg==", + "dependencies": { + "PacketDotNet": "1.4.8", + "System.Memory": "4.6.3", + "System.Text.Encoding.CodePages": "9.0.5" + } + }, + "PacketDotNet": { + "type": "Transitive", + "resolved": "1.4.8", + "contentHash": "j4C4QaJmaPCk0KXsIdsZqmBteKWj5znXBmfbPpu48rE5SW2xwXKVlRf7C3g7VM9aZqMHIQedApEuC71nNX5PaQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + } + } + } +} From 31e682aed58bc011c1104ed2c4b295de873ba05b Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:09:26 +0700 Subject: [PATCH 09/25] Commit generated subscriber dependency lock --- src/ARSVIN.Subscriber/packages.lock.json | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/ARSVIN.Subscriber/packages.lock.json diff --git a/src/ARSVIN.Subscriber/packages.lock.json b/src/ARSVIN.Subscriber/packages.lock.json new file mode 100644 index 0000000..c95b8dd --- /dev/null +++ b/src/ARSVIN.Subscriber/packages.lock.json @@ -0,0 +1,47 @@ +{ + "version": 2, + "dependencies": { + "net8.0-windows7.0": { + "PacketDotNet": { + "type": "Transitive", + "resolved": "1.4.8", + "contentHash": "j4C4QaJmaPCk0KXsIdsZqmBteKWj5znXBmfbPpu48rE5SW2xwXKVlRf7C3g7VM9aZqMHIQedApEuC71nNX5PaQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + }, + "arsvin.engine": { + "type": "Project", + "dependencies": { + "SharpPcap": "[6.3.1, )" + } + }, + "SharpPcap": { + "type": "CentralTransitive", + "requested": "[6.3.1, )", + "resolved": "6.3.1", + "contentHash": "EWclXz+QdffBRppFR7GDBLyKiAz045RGvu4t4gcMGocVMEq6dRfCnAEx7Ep6qxcPPhH2kz13Y8FqBaHZhsh3Pg==", + "dependencies": { + "PacketDotNet": "1.4.8", + "System.Memory": "4.6.3", + "System.Text.Encoding.CodePages": "9.0.5" + } + } + } + } +} From b2a1e8dfe3fbef4ad16f7f64c3bf81bb8c158b67 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:10:04 +0700 Subject: [PATCH 10/25] Commit generated test dependency lock --- tests/ARSVIN.Tests/packages.lock.json | 160 ++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 tests/ARSVIN.Tests/packages.lock.json diff --git a/tests/ARSVIN.Tests/packages.lock.json b/tests/ARSVIN.Tests/packages.lock.json new file mode 100644 index 0000000..8e285dc --- /dev/null +++ b/tests/ARSVIN.Tests/packages.lock.json @@ -0,0 +1,160 @@ +{ + "version": 2, + "dependencies": { + "net8.0": { + "coverlet.msbuild": { + "type": "Direct", + "requested": "[6.0.4, )", + "resolved": "6.0.4", + "contentHash": "Qa7Hg+wrOMDKpXVn2dw4Wlun490bIWsFW0fdNJQFJLZnbU27MCP0HJ2mPgS+3EQBQUb0zKlkwiQzP+j38Hc3Iw==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.7.0, )", + "resolved": "18.7.0", + "contentHash": "49xH9j4UzCh2hMohJp53g3wUTvyycECw7CtVht4gfCz5ykudB1uBcF6D0TtgJPjCtP76UPW53bQElKdCeX+dUg==", + "dependencies": { + "Microsoft.CodeCoverage": "18.7.0", + "Microsoft.TestPlatform.TestHost": "18.7.0" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.9.3, )", + "resolved": "2.9.3", + "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==", + "dependencies": { + "xunit.analyzers": "1.18.0", + "xunit.assert": "2.9.3", + "xunit.core": "[2.9.3]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.5, )", + "resolved": "3.1.5", + "contentHash": "tKi7dSTwP4m5m9eXPM2Ime4Kn7xNf4x4zT9sdLO/G4hZVnQCRiMTWoSZqI/pYTVeI27oPPqHBKYI/DjJ9GsYgA==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.7.0", + "contentHash": "+wFfx9s7D9wegM0RziXMj2kvYDT4qcqXXtyjiQwSZOGQ2wwcOAJQcD6eQXk02jt0MvRNawtp8TJxTrV+wD8X1g==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.7.0", + "contentHash": "6rmgU4q3/WOpOPcncI0YW0Q/QpcQtwR2TTEXDR5+4TfSimPBAk6Z/BgKLeGgp1SOun0ROVUCCafXhRLwsHaPpA==", + "dependencies": { + "System.Reflection.Metadata": "8.0.0" + } + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.7.0", + "contentHash": "kYwfmebCs8992zaxEDkvG7S+YEouTeKfYVKUFEkwh1W2dIoOaevBt80XSKVXCUFEhusjOIm1sFfHBnoJgygrRA==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.7.0", + "Newtonsoft.Json": "13.0.3" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "PacketDotNet": { + "type": "Transitive", + "resolved": "1.4.8", + "contentHash": "j4C4QaJmaPCk0KXsIdsZqmBteKWj5znXBmfbPpu48rE5SW2xwXKVlRf7C3g7VM9aZqMHIQedApEuC71nNX5PaQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.6.3", + "contentHash": "qdcDOgnFZY40+Q9876JUHnlHu7bosOHX8XISRoH94fwk6hgaeQGSgfZd8srWRZNt5bV9ZW2TljcegDNxsf+96A==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==", + "dependencies": { + "System.Collections.Immutable": "8.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.18.0", + "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA==" + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]", + "xunit.extensibility.execution": "[2.9.3]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==", + "dependencies": { + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.9.3", + "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==", + "dependencies": { + "xunit.extensibility.core": "[2.9.3]" + } + }, + "arsvin.engine": { + "type": "Project", + "dependencies": { + "SharpPcap": "[6.3.1, )" + } + }, + "SharpPcap": { + "type": "CentralTransitive", + "requested": "[6.3.1, )", + "resolved": "6.3.1", + "contentHash": "EWclXz+QdffBRppFR7GDBLyKiAz045RGvu4t4gcMGocVMEq6dRfCnAEx7Ep6qxcPPhH2kz13Y8FqBaHZhsh3Pg==", + "dependencies": { + "PacketDotNet": "1.4.8", + "System.Memory": "4.6.3", + "System.Text.Encoding.CodePages": "9.0.5" + } + } + } + } +} From 7ecccb1c0b424b51d31408d6ecc7863989c87be6 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:10:38 +0700 Subject: [PATCH 11/25] Enforce locked NuGet restore in validated automation --- Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Build.props b/Directory.Build.props index 63164ad..ab5ab4f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,6 +7,7 @@ true true true + true 0.3.1 https://github.com/masarray/arsvin git From 2c745cacda2eedce831450cf24246d40604d5052 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:10:50 +0700 Subject: [PATCH 12/25] Restore the solution in locked mode --- build.ps1 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/build.ps1 b/build.ps1 index eea6880..3506c34 100644 --- a/build.ps1 +++ b/build.ps1 @@ -2,6 +2,7 @@ $ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest $root = $PSScriptRoot +$solution = Join-Path $root 'ARSVIN.sln' $appProject = Join-Path $root 'src\ARSVIN\ARSVIN.csproj' $subscriberProject = Join-Path $root 'src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj' $testProject = Join-Path $root 'tests\ARSVIN.Tests\ARSVIN.Tests.csproj' @@ -18,10 +19,8 @@ function Invoke-DotNet { } } -Write-Host '==> Restoring solution projects' -Invoke-DotNet -Arguments @('restore', $appProject) -Invoke-DotNet -Arguments @('restore', $subscriberProject) -Invoke-DotNet -Arguments @('restore', $testProject) +Write-Host '==> Restoring locked solution dependency graph' +Invoke-DotNet -Arguments @('restore', $solution, '--locked-mode') Write-Host '==> Building ARSVIN Publisher' Invoke-DotNet -Arguments @('build', $appProject, '-c', 'Release', '--no-restore', '-warnaserror') From 2b889c6bd90bf9de213e4bcfd489402f8f6dd6f3 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:11:14 +0700 Subject: [PATCH 13/25] Enforce committed NuGet locks in CI --- .github/workflows/ci.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e7f78e..a041ce4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,11 @@ jobs: uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5 with: dotnet-version: 8.0.4xx + cache: true + cache-dependency-path: | + Directory.Packages.props + src/**/packages.lock.json + tests/**/packages.lock.json - name: Build public site and HTML documentation run: python scripts/build-public-site.py --output artifacts/public-site @@ -30,10 +35,10 @@ jobs: shell: pwsh run: .\scripts\validate-public-site.ps1 -SiteRoot artifacts/public-site - - name: Restore solution and generate NuGet lock files - run: dotnet restore ARSVIN.sln --use-lock-file + - name: Restore locked NuGet dependency graph + run: dotnet restore ARSVIN.sln --locked-mode - - name: Upload generated NuGet lock files + - name: Upload committed NuGet lock evidence uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: arsvin-nuget-lockfiles @@ -63,7 +68,7 @@ jobs: retention-days: 14 - name: Publisher dependency vulnerability report - run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive + run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive --no-restore - name: Subscriber dependency vulnerability report - run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive + run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive --no-restore From b3cd559586fcd660a5bd10ab6b9f195f7ff5ca91 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:11:40 +0700 Subject: [PATCH 14/25] Restore locked dependencies in CodeQL --- .github/workflows/codeql.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 13692c5..8c4996e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,6 +24,11 @@ jobs: uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5 with: dotnet-version: 8.0.4xx + cache: true + cache-dependency-path: | + Directory.Packages.props + src/**/packages.lock.json + tests/**/packages.lock.json - name: Initialize CodeQL uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4 @@ -31,8 +36,8 @@ jobs: languages: csharp build-mode: manual - - name: Restore solution - run: dotnet restore ARSVIN.sln + - name: Restore locked solution dependency graph + run: dotnet restore ARSVIN.sln --locked-mode - name: Build solution with warnings as errors run: dotnet build ARSVIN.sln -c Release --no-restore -warnaserror From b63f7fa0bbc4fdac7d7f021beb8f8ea8310c5f0d Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:12:19 +0700 Subject: [PATCH 15/25] Publish release artifacts from the locked dependency graph --- scripts/publish-release.ps1 | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/scripts/publish-release.ps1 b/scripts/publish-release.ps1 index 0d9b52e..30c1109 100644 --- a/scripts/publish-release.ps1 +++ b/scripts/publish-release.ps1 @@ -14,6 +14,7 @@ $tempRoot = Join-Path $artifactRoot 'publish-temp' $portableRoot = Join-Path $artifactRoot 'ARSVIN-win-x64' $installerInput = Join-Path $artifactRoot 'installer-input' +$solution = Join-Path $root 'ARSVIN.sln' $publisherProject = Join-Path $root 'src\ARSVIN\ARSVIN.csproj' $subscriberProject = Join-Path $root 'src\ARSVIN.Subscriber\ARSVIN.Subscriber.csproj' $testProject = Join-Path $root 'tests\ARSVIN.Tests\ARSVIN.Tests.csproj' @@ -89,17 +90,20 @@ Reset-Directory $portableRoot Reset-Directory $installerInput if (-not $SkipTests) { - Write-Host '==> Restoring and testing' - Invoke-DotNet -Arguments @('restore', $publisherProject) - Invoke-DotNet -Arguments @('restore', $subscriberProject) - Invoke-DotNet -Arguments @('restore', $testProject) - Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore') + Write-Host '==> Restoring locked solution graph and testing' + Invoke-DotNet -Arguments @('restore', $solution, '--locked-mode') + Invoke-DotNet -Arguments @('test', $testProject, '-c', 'Release', '--no-restore', '/p:TreatWarningsAsErrors=true') } +Write-Host "==> Restoring locked publish graph for $Runtime" +Invoke-DotNet -Arguments @('restore', $publisherProject, '-r', $Runtime, '--locked-mode') +Invoke-DotNet -Arguments @('restore', $subscriberProject, '-r', $Runtime, '--locked-mode') + $commonPublishArguments = @( '-c', 'Release', '-r', $Runtime, '--self-contained', 'true', + '--no-restore', '-p:PublishSingleFile=true', '-p:IncludeNativeLibrariesForSelfExtract=true', '-p:EnableCompressionInSingleFile=true', From cdefafa4ea85c788a22a4b876d773f7610f41129 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:12:48 +0700 Subject: [PATCH 16/25] Use locked restore for coverage tests --- scripts/test-with-coverage.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test-with-coverage.ps1 b/scripts/test-with-coverage.ps1 index 4921cc7..727dbbb 100644 --- a/scripts/test-with-coverage.ps1 +++ b/scripts/test-with-coverage.ps1 @@ -34,6 +34,7 @@ if ($NoRestore) { # whole-engine baseline, while the regression gate below is calculated over # the protocol-core surface that has an established test baseline. $arguments += @( + '/p:RestoreLockedMode=true', '/p:TreatWarningsAsErrors=true', '/p:CollectCoverage=true', '/p:Include=[ARSVIN.Engine]*', From 02e06bd82776c33afeb03f68702a85f35d506cad Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:13:29 +0700 Subject: [PATCH 17/25] Record P1 dependency and release hardening --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ead379d..2e7bc9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,20 @@ All notable ARSVIN changes are documented here using a lightweight Keep a Change - Added unique canonical URLs, descriptions, Open Graph metadata, Twitter Card metadata, and `TechArticle` JSON-LD for engineering documentation pages. - Added a generated multi-page sitemap containing the product homepage and every published documentation page. - 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. ### Changed - GitHub Pages and Windows CI now build and validate the same staged public-site artifact instead of copying raw Markdown into the deployment directory. - 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. + +### 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. ### Planned From f335f470f86cea9680cca203da8a18fff6557063 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:16:30 +0700 Subject: [PATCH 18/25] Generate win-x64 runtime dependency locks --- .github/workflows/ci.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a041ce4..b4c3514 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,12 @@ jobs: - name: Restore locked NuGet dependency graph run: dotnet restore ARSVIN.sln --locked-mode - - name: Upload committed NuGet lock evidence + - name: Refresh win-x64 application lock graphs + run: | + dotnet restore src/ARSVIN/ARSVIN.csproj -r win-x64 --force-evaluate + dotnet restore src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -r win-x64 --force-evaluate + + - name: Upload generated NuGet lock evidence uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: arsvin-nuget-lockfiles @@ -68,7 +73,7 @@ jobs: retention-days: 14 - name: Publisher dependency vulnerability report - run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive --no-restore + run: dotnet list src/ARSVIN/ARSVIN.csproj package --vulnerable --include-transitive - name: Subscriber dependency vulnerability report - run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive --no-restore + run: dotnet list src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj package --vulnerable --include-transitive From b2bbb01afe38985b4dfed87e87ab22e7b45d45ad Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:18:18 +0700 Subject: [PATCH 19/25] Lock Publisher win-x64 runtime dependencies --- src/ARSVIN/packages.lock.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ARSVIN/packages.lock.json b/src/ARSVIN/packages.lock.json index c95b8dd..4cd2cb6 100644 --- a/src/ARSVIN/packages.lock.json +++ b/src/ARSVIN/packages.lock.json @@ -42,6 +42,13 @@ "System.Text.Encoding.CodePages": "9.0.5" } } + }, + "net8.0-windows7.0/win-x64": { + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + } } } } From 812c95f4c5aa9a2f6fbcbc2a7f1d55757650bfc6 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:18:41 +0700 Subject: [PATCH 20/25] Lock Subscriber win-x64 runtime dependencies --- src/ARSVIN.Subscriber/packages.lock.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ARSVIN.Subscriber/packages.lock.json b/src/ARSVIN.Subscriber/packages.lock.json index c95b8dd..4cd2cb6 100644 --- a/src/ARSVIN.Subscriber/packages.lock.json +++ b/src/ARSVIN.Subscriber/packages.lock.json @@ -42,6 +42,13 @@ "System.Text.Encoding.CodePages": "9.0.5" } } + }, + "net8.0-windows7.0/win-x64": { + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + } } } } From 2fbe68c057763bb53bad48e6cc592cd07d67695a Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:19:10 +0700 Subject: [PATCH 21/25] Finalize locked NuGet restore in CI --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4c3514..2ac4f70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,12 +38,7 @@ jobs: - name: Restore locked NuGet dependency graph run: dotnet restore ARSVIN.sln --locked-mode - - name: Refresh win-x64 application lock graphs - run: | - dotnet restore src/ARSVIN/ARSVIN.csproj -r win-x64 --force-evaluate - dotnet restore src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj -r win-x64 --force-evaluate - - - name: Upload generated NuGet lock evidence + - name: Upload committed NuGet lock evidence uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: arsvin-nuget-lockfiles From 4a12753be3f23aabd83b0c2f85c16be3b14f3354 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:21:14 +0700 Subject: [PATCH 22/25] Declare supported win-x64 runtime for Publisher --- src/ARSVIN/ARSVIN.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ARSVIN/ARSVIN.csproj b/src/ARSVIN/ARSVIN.csproj index f1ed1d9..7ecc371 100644 --- a/src/ARSVIN/ARSVIN.csproj +++ b/src/ARSVIN/ARSVIN.csproj @@ -3,6 +3,7 @@ WinExe net8.0-windows + win-x64 true ARSVIN ARSVIN From e87568aee929078ee9f09138ca4801b46b29752e Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:21:31 +0700 Subject: [PATCH 23/25] Declare supported win-x64 runtime for Subscriber --- src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj b/src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj index 0583740..67ad17e 100644 --- a/src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj +++ b/src/ARSVIN.Subscriber/ARSVIN.Subscriber.csproj @@ -3,6 +3,7 @@ WinExe net8.0-windows + win-x64 true ARSVIN.Subscriber ARSVIN.Subscriber From 63ea95f836f9b27ee07f417e92c7f636cdf5fd7e Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:24:45 +0700 Subject: [PATCH 24/25] Declare win-x64 runtime graph for the shared engine --- src/ARSVIN.Engine/ARSVIN.Engine.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ARSVIN.Engine/ARSVIN.Engine.csproj b/src/ARSVIN.Engine/ARSVIN.Engine.csproj index 1015115..86ef2fb 100644 --- a/src/ARSVIN.Engine/ARSVIN.Engine.csproj +++ b/src/ARSVIN.Engine/ARSVIN.Engine.csproj @@ -2,6 +2,7 @@ net8.0 + win-x64 ARSVIN.Engine AR.Iec61850 Shared IEC 61850 protocol, SCL, Sampled Values, capture, and transport engine used by ARSVIN Publisher and Subscriber. From 51204bd3568db66b6c05d333bdc12432450b73c6 Mon Sep 17 00:00:00 2001 From: masarray Date: Sun, 12 Jul 2026 16:25:06 +0700 Subject: [PATCH 25/25] Lock shared engine win-x64 runtime dependencies --- src/ARSVIN.Engine/packages.lock.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ARSVIN.Engine/packages.lock.json b/src/ARSVIN.Engine/packages.lock.json index 89e6f1d..fa8132c 100644 --- a/src/ARSVIN.Engine/packages.lock.json +++ b/src/ARSVIN.Engine/packages.lock.json @@ -36,6 +36,13 @@ "resolved": "9.0.5", "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" } + }, + "net8.0/win-x64": { + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "9.0.5", + "contentHash": "P6gqCJcVjdWA50Eai95eYdG4ryrb1xCd770NhQrvj847C7m30CJwQqzKykWoEMvV4qvjUazL/m7UMQdMZTp5xw==" + } } } }