From 9b78395d38cfb218e9122df7e771b1ef69e641b1 Mon Sep 17 00:00:00 2001 From: florentianayuwono Date: Wed, 7 Oct 2026 00:42:03 +0700 Subject: [PATCH 1/2] test(worker): scope Alpine-container Node tests to X64 builds StepHost.CheckPlatformForAlpineContainer gates Alpine Node support on Constants.Runner.PlatformArchitecture.Equals(Constants.Architecture.X64). That value is baked in at compile time via the X64/ARM/ARM64 preprocessor symbols (set from the PackageRuntime MSBuild property), not detected at test-runtime. When the Test assembly is built natively on a linux-arm64 self-hosted runner (no explicit PackageRuntime override), PlatformArchitecture compiles to Arm64, so these three tests deterministically throw NotSupportedException instead of exercising the Alpine-specific behavior they were written for. This was previously invisible because a dead matrix condition in build.yml meant the L0 test step never actually ran on the linux-arm64 leg. Gate the three Alpine-container tests with #if X64 so they only compile/run against X64-targeted Test assembly builds, matching the production code's own intentional restriction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Test/L0/Worker/StepHostL0.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Test/L0/Worker/StepHostL0.cs b/src/Test/L0/Worker/StepHostL0.cs index bac7d41d90a..6030320101f 100644 --- a/src/Test/L0/Worker/StepHostL0.cs +++ b/src/Test/L0/Worker/StepHostL0.cs @@ -55,6 +55,11 @@ public async Task DetermineNodeRuntimeVersionInContainerAsync() } } + // Alpine-container Node support is only implemented for X64 (see StepHost.CheckPlatformForAlpineContainer, + // which throws NotSupportedException for any other Constants.Runner.PlatformArchitecture). That value is + // baked in at compile time via this same X64/ARM/ARM64 preprocessor symbol, so these tests can only pass + // when the Test assembly itself is built targeting X64. +#if X64 [Fact] [Trait("Level", "L0")] [Trait("Category", "Worker")] @@ -108,6 +113,7 @@ public async Task DetermineNode20RuntimeVersionInAlpineContainerAsync() Assert.Equal("node20_alpine", nodeVersion); } } +#endif [Fact] [Trait("Level", "L0")] @@ -163,6 +169,9 @@ public async Task DetermineNode20RuntimeVersionInUnknowContainerAsync() } } + // See the comment above DetermineNodeRuntimeVersionInAlpineContainerAsync: Alpine-container Node support + // is X64-only in production code, so this test is only valid for X64-targeted Test assembly builds. +#if X64 [Fact] [Trait("Level", "L0")] [Trait("Category", "Worker")] @@ -189,6 +198,7 @@ public async Task DetermineNode24RuntimeVersionInAlpineContainerAsync() Assert.Equal("node24_alpine", nodeVersion); } } +#endif [Fact] [Trait("Level", "L0")] From dc0ef4993887397363842779034bbf4088a91365 Mon Sep 17 00:00:00 2001 From: florentianayuwono Date: Tue, 6 Oct 2026 13:34:14 +0700 Subject: [PATCH 2/2] fix(ci): correct broken L0 test matrix condition in build.yml The 'L0' step's condition compared matrix.runtime (always 'linux-*'- prefixed, e.g. 'linux-x64', 'linux-arm64') against bare arch names ('arm64', 'amd64') that only ever appear in the separate matrix.runs_on field. This mismatch meant the condition never evaluated true for any matrix leg, so ./dev.sh test has silently never run as part of this workflow, on any architecture, on PRs or pushes. Compared against upstream actions/runner's build.yml to confirm intent: upstream runs L0 on every runtime except the ones that can't execute natively on its GitHub-hosted runners (linux-arm64, linux-arm, osx-arm64, win-arm64, since those jobs run cross-compiled on amd64 hosts). This fork instead builds each target on matching self-hosted native hardware (runs-on: matrix.runs_on), so linux-arm64 can safely run its own tests directly, unlike upstream. Fix: compare against the correct matrix.runtime values and enable L0 for linux-x64 and linux-arm64 (native, unpatched builds). linux-arm (32-bit armv7l, cross-targeted), ppc64le, and s390x are intentionally left disabled for now -- they require their respective patches applied first, and their dotnet-test behavior under cross/32-bit targeting is not yet validated. Enabling genuine L0 coverage for those is tracked as separate follow-up work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/build.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ee4a42da564..7b182a4d98c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,7 +75,16 @@ jobs: run: | ./dev.sh test working-directory: src - if: matrix.runtime == 'arm64' || matrix.runtime == 'amd64' + # Compares against matrix.runs_on (bare arch names: amd64/arm64/ppc64le/s390x), not + # matrix.runtime (always 'linux-*'-prefixed) -- the two were previously confused here, + # which meant this condition never evaluated true for any matrix leg and L0 silently + # never ran in this workflow. linux-x64/linux-arm64 build/run natively on matching + # self-hosted hardware with no patches applied, so they're safe to test directly here. + # linux-arm (32-bit armv7l, cross-targeted even though it builds on arm64 hardware), + # ppc64le, and s390x are intentionally left out: they require the arm/ppc64le/s390x + # patches to be applied first and their 32-bit/cross-arch test-tooling behavior under + # dotnet test is not yet validated. + if: matrix.runtime == 'linux-x64' || matrix.runtime == 'linux-arm64' # Create runner package tar.gz/zip - name: Package Release