From 0d86f28720818fa074cba9d48a5e569a3b460a6d Mon Sep 17 00:00:00 2001 From: Ari Sulistiono Date: Thu, 24 Sep 2026 12:24:50 +0700 Subject: [PATCH 1/2] fix(ci): checkout and verify exact trigger SHA for tested Windows build --- .github/workflows/build.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3895b2163..e3183adef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,11 +11,24 @@ jobs: name: Build, test, validate and package Windows application runs-on: windows-latest steps: - - name: Checkout ARSAS application + - name: Checkout exact triggering ARSAS revision + uses: actions/checkout@v4 + with: + path: ArIED61850Tester + ref: ${{ github.sha }} + persist-credentials: false + fetch-depth: 1 + + - name: Verify tested application revision shell: powershell run: | - $ref = if ($env:GITHUB_HEAD_REF) { $env:GITHUB_HEAD_REF } else { $env:GITHUB_REF_NAME } - git clone --quiet --depth 1 --branch $ref "https://github.com/$env:GITHUB_REPOSITORY.git" ArIED61850Tester + $actual = (git -C .\ArIED61850Tester rev-parse HEAD).Trim().ToLowerInvariant() + $expected = $env:GITHUB_SHA.Trim().ToLowerInvariant() + if ($actual -ne $expected) { + throw "CI source revision mismatch. Expected $expected, checked out $actual." + } + "ARSAS_SOURCE_COMMIT=$actual" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + Write-Host "Testing and packaging exact ARSAS source $actual" - name: Resolve immutable ARIEC61850 integration lock shell: powershell From 17b67a4ffc70e2c05ac6cd361523bd561cfa71f5 Mon Sep 17 00:00:00 2001 From: Ari Sulistiono Date: Thu, 24 Sep 2026 12:25:08 +0700 Subject: [PATCH 2/2] test(ci): prevent branch-tip checkout from replacing trigger revision --- .../ExactCiSourceRevisionContractTests.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/ARSAS.Tests/ExactCiSourceRevisionContractTests.cs diff --git a/tests/ARSAS.Tests/ExactCiSourceRevisionContractTests.cs b/tests/ARSAS.Tests/ExactCiSourceRevisionContractTests.cs new file mode 100644 index 000000000..5be58d6ee --- /dev/null +++ b/tests/ARSAS.Tests/ExactCiSourceRevisionContractTests.cs @@ -0,0 +1,39 @@ +namespace ARSAS.Tests; + +/// +/// Locks the CI build to the event's immutable revision. A moving PR branch must +/// never silently change which application source is built, tested or packaged. +/// +public sealed class ExactCiSourceRevisionContractTests +{ + [Fact] + public void WindowsBuild_ChecksOutAndVerifiesTheExactTriggerCommit() + { + var workflow = File.ReadAllText(FindRepositoryFile(".github/workflows/build.yml")); + + Assert.Contains("ref: ${{ github.sha }}", workflow, StringComparison.Ordinal); + Assert.Contains("path: ArIED61850Tester", workflow, StringComparison.Ordinal); + Assert.Contains("persist-credentials: false", workflow, StringComparison.Ordinal); + Assert.Contains("git -C .\\ArIED61850Tester rev-parse HEAD", workflow, StringComparison.Ordinal); + Assert.Contains("$env:GITHUB_SHA.Trim().ToLowerInvariant()", workflow, StringComparison.Ordinal); + Assert.Contains("CI source revision mismatch", workflow, StringComparison.Ordinal); + Assert.Contains("ARSAS_SOURCE_COMMIT=$actual", workflow, StringComparison.Ordinal); + Assert.DoesNotContain("git clone --quiet --depth 1 --branch $ref", workflow, StringComparison.Ordinal); + Assert.Contains("dotnet test .\\ArIED61850Tester\\tests\\ARSAS.Tests", workflow, StringComparison.Ordinal); + Assert.Contains("scripts\\publish-windows-portable.ps1", workflow, StringComparison.Ordinal); + } + + private static string FindRepositoryFile(string relativePath) + { + DirectoryInfo? directory = new(AppContext.BaseDirectory); + while (directory != null) + { + var candidate = Path.Combine(directory.FullName, relativePath); + if (File.Exists(candidate)) + return candidate; + directory = directory.Parent; + } + + throw new FileNotFoundException($"Repository file not found: {relativePath}"); + } +}