ci: keep the build caches alive between bursts of work - #61
Merged
radiosilence merged 1 commit intoAug 8, 2026
Merged
Conversation
The pipeline already caches Rust builds the same way jaritanet does — Swatinem/rust-cache on every compiling job, keyed per target, saving only from main so a pull request cannot evict the entry it restores from. The last run on main hit that cache on both architectures. What it does not have is anything keeping the entries alive: GitHub drops a cache nothing has read for 7 days, and this repo regularly goes quiet for longer, so the caches are simply gone by the time work resumes and the next push compiles ~200 crates from cold on every runner. Builds on main twice a week so the entries stay warm and get re-saved against the current Cargo.lock. Nothing publishes on a schedule — the existing gates on publish and the release already require a push event — and the binary uploads are skipped so a warm-up run leaves no 90-day artefacts. build-darwin joins the schedule despite being release-only: its caches are wanted warm exactly when a release goes out, which is rare enough that they would otherwise always have expired. Also drops `cargo build` from the check job, which only compiled a second time what `cargo test` compiles anyway, and lints the tests by moving clippy to --all-targets --locked. Clippy is clean under it today. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K5PUhckVayB6JLBywqgBP1
radiosilence
marked this pull request as ready for review
August 8, 2026 12:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #60.
The caching was already there
Worth saying up front, because it changes what this PR is: the pipeline
already does what jaritanet does.
Swatinem/rust-cacheis on every job thatcompiles, keyed per target on the matrix legs, with
save-ifrestricted tomainso a pull request restores the shared entry without evicting it. Thelast run on
mainreportsCache hit ... full match: trueandCache up-to-dateon both architectures.The reason
/actions/cachesis empty is that GitHub deletes any cache nothinghas read for 7 days, and this repo goes quiet for longer than that between
bursts of work. The caches were not missing — they expired, and the next push
after a quiet fortnight compiles ~200 crates from cold on all four runners.
That cold run is the slow build in the issue.
What changes
A twice-weekly build on
main(Mon/Thu 06:00 UTC), plusworkflow_dispatch.Reading a cache resets its clock and the job re-saves it against the current
Cargo.lock, so the entries never reach the eviction threshold and the cost ofa cold compile lands on a schedule instead of on whoever pushes next.
Nothing publishes on a schedule, and no new gate was needed for that:
publishand
build-darwinwere already conditioned ongithub.event_name == 'push'.The binary uploads are skipped on schedule runs so a warm-up does not leave a
90-day artefact behind twice a week.
build-darwinnow runs on the schedule too (!= 'pull_request'rather than== 'push'). It is release-only, so its caches are wanted warm exactly when arelease goes out — which is rare enough that under the old condition they had
always expired by then. Public repo, so the macOS runners are free.
cargo builddropped fromcheck.cargo testcompiles the binary aswell, so it was a second pass over the same crates. Clippy moves to
--all-targets --locked, which lints the test code the bare invocation skipped;it is clean under that today (verified locally).
--verbosedropped fromcargo test— it only inflated the log.What is deliberately not copied from jaritanet
The
buildkit-blob-*/index-*entries in jaritanet's cache list are the GHAlayer cache from its reusable publish workflow. Adding those back here would be
a regression: since #54 nothing compiles inside the Dockerfile — it is a
COPYof a prebuilt binary onto distroless — and
mode=maxwas stuffing Rust buildlayers into the same repo-wide 10GB budget
rust-cacheuses, so the two evictedeach other. jaritanet's
misetoolchain cache also has no counterpart; there isno
mise.tomlhere.Verifying
checkand bothbuild-imagelegs must still pass on this PR, restoringfrom
mainand saving nothing (save-ifis false offmain).main— GitHub readsscheduled triggers from the default branch's copy of the workflow. First
proof is either the Monday/Thursday run or a manual
workflow_dispatch;after it,
/actions/cachesshould listv0-rust-*entries forcheck,both
linux-*legs and both*-apple-darwintargets.was also CI-only and left it alone.