perf(ci): build gap-suite's fast-mode archives once, share across shards - #8686
perf(ci): build gap-suite's fast-mode archives once, share across shards#8686jdalton wants to merge 1 commit into
Conversation
Each of gap-suite's 6 PR-tier shards independently ran the exact same 'cargo build --release -p perry -p perry-runtime -p perry-stdlib -p perry-runtime-static -p perry-stdlib-static' - measured at 10.0 minutes per shard against a warm sccache. That is ~50 minutes of pure redundant compute per PR run for identical output. Adds a gap-suite-build job that runs this build once (only in fast mode; full mode's shards genuinely need their own per-test auto-optimize rebuild, which run_gap_tests.sh already handles and this does not touch), uploads the three files the fast-mode harness actually links against (the perry binary, libperry_runtime.a, libperry_stdlib.a), and has every gap-suite shard download them instead of rebuilding. gap-suite's own if: uses always() plus an explicit check on gap-suite-build's result, so a SKIPPED build (full mode, where the job never runs) does not cascade into skipping the shards, while a genuine build FAILURE correctly stops them from starting. Also inlines dtolnay/rust-toolchain and SHA-pins actions/checkout, actions/setup-node, and Swatinem/rust-cache in the existing gap-suite job for local consistency with the new gap-suite-build job right above it - the broader sweep across the rest of the workflow tree is PerryTS#8684, a separate PR.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review. 📝 WalkthroughWalkthroughThe gap suite now builds fast-mode compiler and runtime artifacts once, uploads them, and reuses them across shards. Full mode retains its auto-optimize path. Related workflow actions and toolchains use pinned commit references. ChangesGap suite artifact reuse
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This localized CI workflow change has no actionable merge-blocking risk remaining; it is merge-ready after normal checks and review. Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant gap_suite_build
participant artifact_storage
participant gap_suite
gap_suite_build->>artifact_storage: Upload compiler and runtime archives
gap_suite->>artifact_storage: Download shared archives in fast mode
artifact_storage-->>gap_suite: Return shared artifacts
gap_suite->>gap_suite: Restore compiler executable permissions
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…CI hardening (#8696) Lands #8687, #8686 and #8684. #8687 (closes #8679) replaces the post-RS4GC instruction-budget hard refusal with a typed spill-retry: an already-lowered LlFunction switches from native statepoint roots to a complete precise shadow frame and the unit is rebuilt at the originally requested optimization level. This is the durable handling for the estimator misses #8678 could only make more accurate. Retry termination is guaranteed rather than argued. `request_shadow_frame_spill()` latches on `force_shadow_frame` and returns false if already set; `apply_budget_spill_retry` records only the functions where it returned true, and any violation not recorded becomes a hard error naming it. A function therefore cannot be retried twice. #8686 builds the gap suite's fast-mode archives once in a dedicated `gap-suite-build` job and shares them across the six shards. The skipped-vs-failed distinction is handled explicitly: `always()` keeps a SKIPPED build (full mode, where the job never runs) from cascading into skipped shards, while the guard still requires `success` or `skipped`, so a genuine build FAILURE stops the shards. The shard also verifies the downloaded binary is runnable and exports PERRY_BIN / PERRY_RUNTIME_DIR. #8684 inlines dtolnay/rust-toolchain and SHA-pins every other third-party action. Verified no job and no gate is dropped: the single removed step is the fast-mode archive build, which moved into gap-suite-build. No version bump. Co-authored-by: Ralph Küpper <ralph@skelpo.com>
|
Landed on The thing I checked hardest was the skipped-vs-failed distinction, since a skipped job satisfies a dependency and that has produced gates here that couldn't fail. Your guard gets it right: Validated on the merged result: all 30 lint checkers, codegen 1202/0, runtime 2655/0, perry-bin 1031/0. Thanks! |
Summary
Cuts roughly 50 minutes of pure redundant compute from every PR run by building gap-suite's fast-mode release archives once instead of independently rebuilding them in each of the 6 parallel shards.
What was happening and the measured cost
Every
gap-suiteshard runscargo build --release -p perry -p perry-runtime -p perry-stdlib -p perry-runtime-static -p perry-stdlib-staticbefore running its own slice of the suite. I pulled the actual per-step timing from a real PR run: that build step alone took 10.0 minutes, and it produces byte-identical output in every shard, since all 6 shards build from the same commit with the same flags.Because the shards run in parallel, this did not directly cost PR wall-clock time. It did cost roughly 50 minutes of runner compute per PR run (5 unnecessary repeats of a 10-minute build), and on a capacity-limited runner pool that compute pressure can itself delay when other queued jobs get a slot.
Changes
Adds a
gap-suite-buildjob that runs only when the plan selects fast mode (PR and sweep tiers; full mode's shards genuinely need their own per-test auto-optimize rebuild throughrun_gap_tests.sh, which this does not touch). It builds once, then uploads the three files the fast-mode harness actually links against: theperrybinary,libperry_runtime.a, andlibperry_stdlib.a. Everygap-suiteshard now downloads that artifact instead of rebuilding, restoring the binary's executable bit defensively after the download.gap-suite's ownif:condition usesalways()together with an explicit check ongap-suite-build's result, so a build that is correctly SKIPPED (full mode) does not cascade into skipping the shards, while a genuine build FAILURE still stops them from starting rather than running six shards doomed to fail identically.While in this section of the file, I also inlined
dtolnay/rust-toolchainand SHA-pinnedactions/checkout,actions/setup-node, andSwatinem/rust-cachein the existinggap-suitejob, for local consistency with the new job right above it. The broader sweep across the rest of the workflow tree is a separate PR, #8684, since that change is unrelated to this one in scope.Related issue
n/a
Test plan
I confirmed the per-step timing of the redundant build against a real PR run (
https://github.com/PerryTS/perry/actions/runs/32674242904, shard 5's job), which showed the 10.0-minute build step. I traced the fan-ingatejob's own gating script and confirmed it only inspects the result of jobs explicitly listed in its ownneeds:array, which does not includegap-suite-build— so the new job is fully transparent to branch protection, and onlygap-suite's own result affects it. I validated the edited workflow file as YAML and ranactionlintagainst it before and after this change; the only differences are line-number shifts in three pre-existing shellcheck findings elsewhere in the file, with no new findings introduced. I have not been able to run this workflow for real, since that requires a merge to actually exercise the new job graph on this repository's runners.Checklist
I have not bumped the workspace version or edited CLAUDE.md or CHANGELOG.md. My commit follows the
perf:prefix convention used in the log. I have read CONTRIBUTING.md and agree to the Code of Conduct.Summary by CodeRabbit