Skip to content

ci: spec22-gems msys harness reads the arch off the package (arm64 dogfood) - #112

Merged
ronaldtse merged 1 commit into
mainfrom
ci/spec22-msys-arch-detection
Sep 22, 2026
Merged

ronaldtse merged 1 commit into
mainfrom
ci/spec22-msys-arch-detection

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Why

tebako-runtime-ruby#180's new windows/arm64 dogfood leg (run 35685304693) failed inside this harness: the msys row of the spec22-gems acceptance hardcoded x64 in three places, and the arm64 leg needs all three to follow the architecture:

  • PE_DLL spelled x64-ucrt-ruby<ABI>.dll — the arm64 exe's PE import is aarch64-ucrt-ruby400.dll (the factory's RubyVersion::MSYS_DLL_CPU_TAGS owns the mapping; the arm64 spelling is proven by the arm64 legs' own toolchain).
  • The devkit import library matched libx64-ucrt-ruby*.dll.a — arm64 ships libaarch64-ucrt-ruby400.dll.a.
  • UCRT64_BIN defaulted to ucrt64/bin — the gem-install leg's gcc/make PATH and the DLL-closure vendoring source must be clangarm64/bin on arm64 (an x64 gcc cannot link a native arm64 extension; x64 runtime DLLs cannot load into one).

What

The arch is read off the runtime package's triplet suffix — the artifact name is the contract the factory's env-matrix arch key stamps (-windows-ucrt64 = x64/ucrt64, -windows-ucrt-arm64 = aarch64/clangarm64) — and the three consumers ride it. The staging find also becomes exact (-name …-windows-ucrt64 -o -name …-windows-ucrt-arm64): the old glob could pick the package's .abi / .contract.yaml / .tfs.sha256 sidecars on a readdir-order change.

Proof

  • bash -n clean; shellcheck shows only the pre-existing SC2034 on st_unfixed.
  • The detection block run locally against the real artifacts of factory run 35685304693:
    • arm64 package → CPU_TAG=aarch64, toolchain clangarm64, PE_DLL=aarch64-ucrt-ruby400.dll, DLL + env image found.
    • x64 package → CPU_TAG=x64, toolchain ucrt64, PE_DLL=x64-ucrt-ruby400.dll, DLL + env image found.

Companion

The factory side of the same failure — the dogfood's tfs CLI pin (0.1.9 predates the spec-20 limnifs reader; the arm64 env image is limnifs by design because clangarm64 has no native dwarfs-t) — rides tebako-runtime-ruby#180 as an added commit. This harness fix must land on main before that PR's dogfood step re-runs (PR CI checks the harness out at main).

…gfood)

The windows dogfood hardcoded the x64 row three ways: PE_DLL spelled
x64-ucrt-ruby<ABI>.dll, the devkit import library matched
libx64-ucrt-ruby*.dll.a, and UCRT64_BIN defaulted to the ucrt64
toolchain bin. On the factory's arm64 leg (windows-11-arm,
clangarm64) each is wrong: the PE import is aarch64-ucrt-ruby400.dll,
the import library is libaarch64-ucrt-ruby400.dll.a, and the compiler
PATH must be clangarm64's — an x64 gcc cannot link a native arm64
extension, and vendored x64 runtime DLLs cannot load into one.

The arch is now read off the runtime package's triplet suffix — the
artifact name is the contract the factory stamps — and all three ride
it. The cpu tag mirrors the factory's RubyVersion::MSYS_DLL_CPU_TAGS
(the name's owner; a drifted tag binds nothing, so drift dies loudly
at boot / link). The staging find also becomes exact: the previous
glob could pick the package's .abi / .contract.yaml / .tfs.sha256
sidecars on a readdir-order change.

Surfaced by tebako-runtime-ruby#180's arm64 dogfood leg (run
35685304693): staging passed, then the pinned tfs 0.1.9 CLI could not
open the arm64 env image — limnifs by design (no native dwarfs-t on
clangarm64), a format pre-spec-20 CLIs do not read. The factory side
bumps the CLI pin; this harness side carries the arch-aware naming
the arm64 leg needs once the image opens.
ronaldtse pushed a commit to tamatebako/tebako-runtime-ruby that referenced this pull request Sep 22, 2026
The arm64 leg's env image is limnifs by design — the link unit packs it
because clangarm64 has no native dwarfs-t — and the dogfood's pinned
tfs 0.1.9 predates the spec-20 reader: the first arm64 dogfood (run
35685304693) staged the package and then could not open the image
("Failed to open archive ... Unsupported format"). The x64 leg passed
only because its image is dwarfs-t, which the old CLI still reads.

The pin moves to v2.8.16 (the current release; post-flip limnifs
reader in every shipped CLI) and each leg fetches its own arch's
asset — the native windows-ucrt-arm64 tfs.exe ships since v2.8.16, so
windows-11-arm no longer needs the x64 build under emulation. Local
proof: the v2.8.16 macos CLI lists the arm64 leg's artifact image
(/__tpkg__ /bin /lib /local /ssl); v0.1.9 rejects it.

The harness side of the same leg — arch-aware PE DLL / import library
/ toolchain-bin naming — rides tamatebako/ruby#112; this commit's CI
picks it up once that lands on main (PR CI checks the harness out at
main).
@ronaldtse
ronaldtse merged commit 0eb771b into main Sep 22, 2026
42 checks passed
@ronaldtse
ronaldtse deleted the ci/spec22-msys-arch-detection branch September 22, 2026 05:27
ronaldtse added a commit to tamatebako/tebako-runtime-ruby that referenced this pull request Sep 22, 2026
…on (arm64 slices) (#180)

* dogfood: one spec22-gems leg per architecture the run actually built

The dogfood job was x64-shaped at every binding: runs-on windows-latest,
runtime-packages-windows-x86_64-4.0.6, devkit-windows-x86_64-4.0.6,
msystem ucrt64. An arm64-sliced publish (arch_filter=arm64) computes a
matrix that still contains 4.0.6, so the dogfood ran — then died on
"Artifact not found: runtime-packages-windows-x86_64-4.0.6", because an
arm64 slice builds no x86_64 package (the v0.16.27 arm64 publish, run
35677556225: all 8 arm64 legs published + signed green, then the dogfood
failure failed the gate and withheld the registry audit).

The job is now a per-arch matrix: x86_64 on windows-latest/ucrt64,
arm64 on windows-11-arm/clangarm64, each leg gated on the run's own
env-matrix carrying that arch, each consuming its arch's 4.0.6 package
+ devkit. The arm64 runtime gets the gem-level acceptance natively; the
x64 path is byte-identical to before. The tfs CLI stays the ucrt64
build (x64 emulation on the arm runner — harness tooling, not the
runtime under test); the log artifact names gain the arch suffix.

The gate's needs.dogfood.result aggregation is matrix-safe: a leg the
if excludes is skipped, and an all-skipped dogfood reports skipped, so
non-windows and audit runs gate exactly as before.

* audit: never expect a windows/arm64 package for an incapable ruby

expected_package_names computed the plain env × ruby cross product, but
the build matrix drops incapable (version × arch) pairs via the
exclude-matrix — so the arm64 audit of v0.16.27 demanded 42 assets for
3.1/3.2/3.3 rubies the architecture does not serve and failed the
release as incomplete (run 35683750004), withholding the registry
render.

The expectation now filters through the capability rule's single owner,
RubyVersion#msys_arm64_capable? — the same predicate the exclude-matrix
consumes. Specs: an arm64 env expects 3.4.10 but never 3.3.12, and the
x64 control keeps expecting 3.3.12 (the floor gates arm64 only).

Full suite: 416 examples, 0 failures; rubocop clean.

* dogfood: matrix over the run's env rows — matrix context predates job-level if

The first cut gated the per-arch dogfood legs in the job-level `if`,
but GitHub evaluates jobs.<id>.if BEFORE the strategy matrix expands —
matrix.* is undefined there and the workflow fails validation at
queue time (the build-<platform> runs on 5aeeace, 0 jobs). The build
job's own comment documents exactly this rule; I rediscovered it the
hard way.

The dogfood now matrices over needs.compute.outputs.env-matrix directly
— the run's own env rows ARE the arch slice, so an arch-sliced publish
dogfoods exactly the arches it built and no gate expression is needed.
The runner comes from the row's own `host` field; the msystem ternary
mirrors the build legs' (line ~973) spelling.

* dogfood: tfs CLI pin to v2.8.16, per-arch asset (limnifs env images)

The arm64 leg's env image is limnifs by design — the link unit packs it
because clangarm64 has no native dwarfs-t — and the dogfood's pinned
tfs 0.1.9 predates the spec-20 reader: the first arm64 dogfood (run
35685304693) staged the package and then could not open the image
("Failed to open archive ... Unsupported format"). The x64 leg passed
only because its image is dwarfs-t, which the old CLI still reads.

The pin moves to v2.8.16 (the current release; post-flip limnifs
reader in every shipped CLI) and each leg fetches its own arch's
asset — the native windows-ucrt-arm64 tfs.exe ships since v2.8.16, so
windows-11-arm no longer needs the x64 build under emulation. Local
proof: the v2.8.16 macos CLI lists the arm64 leg's artifact image
(/__tpkg__ /bin /lib /local /ssl); v0.1.9 rejects it.

The harness side of the same leg — arch-aware PE DLL / import library
/ toolchain-bin naming — rides tamatebako/ruby#112; this commit's CI
picks it up once that lands on main (PR CI checks the harness out at
main).

---------

Co-authored-by: tebako-ci <tebako@ribose.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants