Skip to content

ci: fan out test jobs from a shared build and move actions to Node 24#224

Merged
LinuxJedi merged 2 commits into
mainfrom
ci/build-fanout-node24
Jul 19, 2026
Merged

ci: fan out test jobs from a shared build and move actions to Node 24#224
LinuxJedi merged 2 commits into
mainfrom
ci/build-fanout-node24

Conversation

@LinuxJedi

@LinuxJedi LinuxJedi commented Jul 19, 2026

Copy link
Copy Markdown
Owner

CI restructure

The serial Build, test, lint job is replaced by a fan-out:

  • build compiles the release binary plus all test binaries once, then stages the finished binaries (main binary + unit-test, probe_golden, and image_regression executables, located via cargo test --no-run --message-format=json since their filenames are hash-suffixed) into a ~50 MB workflow artifact.
  • unit-tests, probe-golden, and diagrom-smoke run in parallel as needs: build jobs that just download the artifact and execute the binaries directly — no toolchain, no rust-cache, no compile. Test executables are plain libtest binaries, so they accept the usual filters and --ignored/--nocapture flags as-is. The integration harnesses spawn the emulator through the compile-time CARGO_BIN_EXE_copperline path, which is the same absolute path on every hosted runner for this repo, so those jobs copy the binary into target/release first.
  • m68k-core also fans out from build (fail-fast gating only — the vendored crate builds standalone into its own target dir, now cached via workspaces: crates/m68k; previously both m68k jobs cached the root target directory they never built, so the vendored core recompiled cold on every run).
  • lint (rustfmt + clippy) runs alongside the build instead of gating it, since it needs no release binary.
  • wasm, m68k-singlestep, docs, and gdb-remote stay independent as before.

Binaries are handed over as an artifact rather than through a shared cargo cache deliberately: an earlier revision of this branch shared the build tree via a rust-cache shared key, and although the fan-out jobs restored it with a full key match, cargo still recompiled the copperline and vendored copperline-m68k crates in every job — local path crates are fingerprinted by source mtime, and a fresh checkout is always newer than the cached artifacts. The build job keeps a plain rust-cache for cross-run dependency caching.

DiagROM hardening (from review): the extracted ROM's sha256 is now verified on every run, covering the cache-hit path that previously skipped the (zip-only) checksum.

Notes:

  • The unit-test split (--lib --bins equivalent) loses nothing: the crate has zero doctests, and the build job's cargo test --no-run still compile-checks the asset-gated integration tests.
  • No required status checks reference the old job names, so the renames break nothing.

Node 20 deprecation fix

All first-party actions move off the deprecated Node 20 runtime across every workflow: checkout v4 -> v7, upload-artifact v4 -> v7, download-artifact v8, setup-node v4 -> v7, cache v4 -> v6. Each was verified to declare runs.using: node24 at its current major, and the release notes across the jumps contain no breaking changes for this usage. The MyST docs jobs' own node-version moves 20 -> 24 as well, since Node 20 itself is EOL.

Replace the serial Build, test, lint job with a build job that compiles
the release binary and all test binaries once, then shares the build
tree through a rust-cache shared key (cache-workspace-crates keeps the
workspace's own artifacts, not just dependencies). Unit tests, the
probe golden renders, the m68k core tests, and the DiagROM boot smoke
fan out from it in parallel, restoring the cache with save-if: false;
DiagROM no longer rebuilds from scratch. Rustfmt and clippy move to
their own job alongside the build since they do not need the release
binary. The crate has no doctests, so splitting cargo test into
--lib --bins and --test probe_golden loses nothing; the build job's
cargo test --no-run still compile-checks the asset-gated integration
tests.

Both m68k jobs now cache crates/m68k/target (workspaces: crates/m68k);
previously they cached the root target directory they never built, so
the vendored core recompiled cold on every run.

Move all first-party actions off the deprecated Node 20 runtime across
every workflow: checkout v4 -> v7, upload-artifact v4 -> v7,
setup-node v4 -> v7, cache v4 -> v6, all verified to run on node24
with no breaking changes for this usage. The MyST docs jobs' own
Node moves 20 -> 24 as well, since Node 20 is EOL.
Copilot AI review requested due to automatic review settings July 19, 2026 07:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restructures GitHub Actions CI to reduce wall time by fanning test jobs out from a shared build cache, and updates first-party GitHub Actions to versions that run on the newer Node runtime (plus bumps docs workflows to Node 24).

Changes:

  • Replace the monolithic “Build, test, lint” CI job with a cached “build” job and parallel needs: build test jobs (unit-tests, probe-golden, m68k-core, diagrom-smoke), while keeping other jobs independent.
  • Update workflow actions (e.g., actions/checkout, actions/upload-artifact, actions/setup-node, actions/cache) to newer majors and set MyST docs workflows’ Node version to 24.
  • Improve caching for the vendored crates/m68k jobs by targeting that workspace’s target directory.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.github/workflows/ci.yml Fans out CI test jobs from a shared build + rust-cache key; updates several actions and Node versions; refactors DiagROM smoke test to use caching and artifacts.
.github/workflows/windows.yml Bumps checkout/upload-artifact action majors for Windows packaging workflow.
.github/workflows/macos.yml Bumps checkout/upload-artifact action majors for macOS packaging workflow.
.github/workflows/appimage.yml Bumps checkout/upload-artifact action majors for AppImage packaging workflow.
.github/workflows/wasm-demo.yml Bumps checkout action majors for wasm demo publish workflow (including second checkout for site repo).
.github/workflows/docs-site.yml Bumps checkout/setup-node action majors and Node version for docs-site publish workflow.
.github/workflows/docs-release.yml Bumps checkout/setup-node/upload-artifact action majors and Node version for docs PDF release workflow.
.github/workflows/flatpak.yml Bumps checkout action majors for Flatpak CI workflow.
.github/workflows/locks.yml Bumps checkout action major for lockfile verification workflow.
.github/workflows/linux-present.yml Bumps checkout action major for Linux present smoke workflow.
.github/workflows/homebrew.yml Bumps checkout action major for Homebrew style/audit workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml
The shared rust-cache handoff restored with a full key match, yet every
fan-out job still recompiled the copperline and vendored m68k crates:
cargo fingerprints local path crates by source mtime, and each job's
fresh checkout is newer than any cached artifact, so the cached build is
never trusted. Drop the shared-key/cache-workspace-crates mechanism and
have the build job stage the finished binaries (main binary plus the
unit-test, probe_golden, and image_regression executables, located via
cargo's JSON build plan since their names are hash-suffixed) into a
workflow artifact. The test jobs now just download and execute them --
no toolchain, no rust-cache, no compile. The integration harnesses spawn
the emulator through the compile-time CARGO_BIN_EXE_copperline path,
identical on every hosted runner, so those jobs copy the binary into
target/release first.

Also verify the extracted DiagROM's sha256 on every run, covering the
cache-hit path that previously skipped the (zip-only) checksum.
@LinuxJedi
LinuxJedi merged commit a6427bc into main Jul 19, 2026
18 checks passed
@LinuxJedi
LinuxJedi deleted the ci/build-fanout-node24 branch July 19, 2026 07:37
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