Skip to content

ci: warm the main-scoped CI cache so PRs stop building cold#5326

Merged
proggeramlug merged 1 commit into
mainfrom
ci/warm-main-cache
Jun 17, 2026
Merged

ci: warm the main-scoped CI cache so PRs stop building cold#5326
proggeramlug merged 1 commit into
mainfrom
ci/warm-main-cache

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

Why (the part #5324 didn't cover)

#5324 moved sccache to a persisted disk cache — necessary, but not sufficient. While verifying it, I found the deeper reason caches were always empty:

test.yml runs only on pull_request + version tags — never on push to main. And GitHub Actions cache scoping lets a run restore caches only from its own branch or the default branch (main) — never another PR's cache. So with nothing running the cache-producing build on main, no main-scoped cache ever existed, and every fresh PR started cold (~90-103 min, tipping over cargo-test's timeout on perry-runtime/perry-codegen PRs).

The same flaw silently disabled Swatinem/rust-cache everywhere in test.yml: its save-if: refs/heads/main never fires because test.yml doesn't run on main, so target/ was never saved either. (Only node-core-subset.yml's weekly scheduled run happened to save a Linux-perry cache.)

What this adds

A new cache-warm.yml that runs once per main merge touching Rust (crates/**, Cargo.toml, Cargo.lock):

  • Compiles — --no-run — the test binaries of the heaviest crates (perry-runtime, perry-stdlib, perry-codegen, perry), which pull in essentially the whole third-party dependency graph + the big first-party crates (the bulk of cargo-test's compile time). The cheap ext-* crates that follow in cargo-test then reuse those cached units.
  • Saves under the same rust-cache shared-key (<os>-perry) and same sccache key prefix (sccache-<os>-perry-) that test.yml's cargo-test / api-docs-drift / compiler-output-regression jobs restore — so the main-scoped caches now exist for every PR to pick up.
  • Is continue-on-error (a cache warm, never a gate), prunes test binaries between crates to respect the runner disk budget (same reason cargo-test does), and uses concurrency: cancel-in-progress so only the latest main commit warms.

Expected effect

After the first warm run lands on main, PR cargo-test restores a warm cache and should run ~50-60 min instead of ~90-103 min cold. Watch the sccache "stats" step on the warm run and the next PR's sccache "Post" stats to confirm hit rates jump, then the cargo-test timeout (temporarily 180) can come back down.

No production code changes.

test.yml runs only on PRs + tags, never on push to main, and GitHub Actions
cache scoping means PRs can only restore caches from their own branch or the
default branch. With nothing running the cache-producing build on main, no
main-scoped cache existed and every PR built cold (~90-103 min). This also
silently disabled Swatinem/rust-cache (save-if:main never fired).

Add cache-warm.yml: on push to main touching Rust, compile (--no-run) the
heavy crates' test binaries and save under the same rust-cache shared-key +
sccache key prefix test.yml restores. Best-effort (continue-on-error), prunes
between crates for disk, concurrency-cancels superseded warms.
@proggeramlug proggeramlug merged commit 783be20 into main Jun 17, 2026
14 checks passed
@proggeramlug proggeramlug deleted the ci/warm-main-cache branch June 17, 2026 13:50
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.

1 participant