ci: per-ISA parallel runner builds (multi-arch split) #45
ci/multiarch-per-isa-builds
into main
The deferred half of fangorn/anvil-cli#43, now unblocked by the affinity-escape fix (fangorn/anvil#361) being deployed to prod.
What
Splits the single build-runner job into two per-ISA jobs that run in parallel on native-architecture workers:
| Job | runs_on |
Builds |
|---|---|---|
build-arm64 |
[linux, arm64] |
linux/arm64 + macos/arm64 |
build-amd64 |
[linux, amd64] |
linux/amd64 + macos/amd64 |
Each pays only cheap cross-OS codegen within its own ISA — never the slow cross-architecture codegen that made a cold build recompile ring’s C/asm for a foreign arch (a cold macos arm64 cross-compile was 4m33s on the last release run).
Fan-in
A runner can’t share a workspace across workers, so publishing goes through the release-asset API:
build-arch.sh <arch>builds its two targets and, on main, uploads them to a release draft (either job creates it; the duplicate-tag race is tolerated).publish-release.sh(depends_onboth) downloads all four, builds the combinedSHA256SUMS, and publishes. A missing binary fails the download and rolls the draft back — an incomplete release never ships (the #40 property, preserved).ci/release.shnow excludes drafts from the version computation, so the run’s own draft doesn’t bump the version out from under the parallel jobs.
What this PR run validates
Publishing is main-only, so this PR run is safe — it exercises the parallel per-ISA builds and the affinity routing (build-arm64 → arm worker, build-amd64 → amd worker, concurrently) without cutting a release. That’s the risky part proven before any release logic runs.
Merging activates the publish path on main; I’ll watch that release cut.
Supersedes ci/build-runner.sh.