Repository navigation
ci: a Zig cache is one cold build, saved once - #233
Merged
Merged
Conversation
Every other CI run on main built from nothing. setup-zig saved each run's `.zig-cache` under a new key and restored the newest, so a warm run saved what it restored plus everything it rebuilt: Linux's test cache went from 3.7 GB to 6-7 GB in one run, passed the 5 GiB limit, and setup-zig cleared it and saved it empty (run 37682171347: "Cache directory reached 6943035149 bytes ... clearing cache"). The next run restored the empty cache (37785306976: 188 B) and started cold. The near-duplicates also filled the repo's 10 GB of Actions cache. setup-zig's caching is off (`use-cache: false`; it still points ZIG_GLOBAL_CACHE_DIR and ZIG_LOCAL_CACHE_DIR at `.zig-cache`). Each job restores and saves that directory with actions/cache under a fixed key: Zig version, job, OS, arch, and the hash of every build.zig.zon, taken before anything is unpacked. A fixed key can't be overwritten, so only a run that missed saves, and only if it succeeded. A job's cache is one complete cold build, and every later run with the same dependencies starts from it. The Windows cross-build's key was still worked out inline, the bug the test job's comment describes: it saved under a hash taken after the fetch unpacked zig-pkg/, so every restore missed. It now takes its key from a step like the others. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
foxnne
force-pushed
the
ci/zig-cache-once
branch
from
October 8, 2026 14:12
e304a95 to
19eb70d
Compare
2 of 3 tasks
foxnne
added a commit
that referenced
this pull request
Oct 8, 2026
A pull request restores its Zig caches from its own earlier runs or from main's; a cache a pull request saves is visible to that pull request alone. A push to main ran only the Linux jobs, so main never held a macOS, Windows or cross-build cache and every pull request's first run built those three cold (#233's warm runs took 43 s, 285 s and 50 s against 389 s, 501 s and 365 s cold). A push to main now runs what a pull request runs: the three-platform test matrix and the Windows cross-build. The merge that changes a dependency saves the new caches under main, a cache GitHub evicts after a quiet week comes back on the next merge, and every merge is tested on all three platforms. Nothing waits on a main run, and with a cache hit the extra jobs are short. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
foxnne
added a commit
that referenced
this pull request
Oct 8, 2026
A pull request restores its Zig caches from its own earlier runs or from main's; a cache a pull request saves is visible to that pull request alone. A push to main ran only the Linux jobs, so main never held a macOS, Windows or cross-build cache and every pull request's first run built those three cold (#233's warm runs took 43 s, 285 s and 50 s against 389 s, 501 s and 365 s cold). A push to main now runs what a pull request runs: the three-platform test matrix and the Windows cross-build. The merge that changes a dependency saves the new caches under main, a cache GitHub evicts after a quiet week comes back on the next merge, and every merge is tested on all three platforms. Nothing waits on a main run, and with a cache hit the extra jobs are short. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
foxnne
added a commit
that referenced
this pull request
Oct 8, 2026
) Follow-up from #233. ## What changes **Every pull request's first run now gets warm macOS, Windows and cross-build caches.** The only caches every PR can restore are the ones saved by a run on `main`; a cache a PR saves is visible to that PR alone. A push to `main` ran only the Linux jobs, so `main` never held a macOS, Windows or cross-build cache, and each PR's first run built those three cold. From #233's runs: | Job | Cold | Warm | |---|---|---| | macOS tests | 389 s | 43 s | | Windows tests | 501 s | 285 s | | Windows cross-build | 365 s | 50 s | The warm numbers were on unchanged source; a typical PR rebuilds the app and gains less. **Now a push to `main` runs what a PR runs:** the three-platform test matrix and the Windows cross-build. That gives three things with no schedule and no new trigger: - **The merge that changes a dependency saves the new caches to `main` in the same run.** PRs opened after that merge start warm. - **A cache GitHub evicts after 7 unused days comes back on the next merge.** - **Every merge is tested on all three platforms, not only Linux.** **Cost:** three more jobs per merge. They're free on a public repo, short on a cache hit, and nothing waits on a `main` run, since PRs are gated by `ci-ok`. (This replaces a first version that added a nightly scheduled run instead.) ## SDK impact - [x] None ## Verified - [x] The workflow parses. - Triggers are unchanged: `push` to main, `pull_request`, `merge_group`, `workflow_dispatch`. - The matrix is the three platforms for every event. - The cross-build runs whenever the builds run. - No other check reads `github.event_name` except the `changes` job's diff base. - [ ] **Live, after merge:** the merge's own push run should save `zig-0.16.0-test-macOS-ARM64-…`, `…-test-Windows-X64-…` and `…-windows-fizzy-backend-Linux-X64-…` under `refs/heads/main`. `main` already holds the Linux test and integration caches. The next PR's first run should then restore all five. ## Follow-ups None. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Follows #232, now merged; rebased onto
main. It touches onlyci.yml.What changes
Every other CI run on
mainwas building from nothing, and this fixes it. I first guessed that cancelled runs were the cause. The logs show otherwise:main, 10-05main, 10-07main, 10-08The cause is how setup-zig caches. It saves each run under a new key and restores the newest, so a warm run saves what it restored plus everything it rebuilt. For Linux, one run is enough to go past the limit, and an over-limit cache is saved empty. Cancellation only took part because cancelled runs grow too. The near-duplicates also fill the repo's 10 GB of Actions cache, which stood at 9.6 GB.
Now:
use-cache: false). It still pointsZIG_GLOBAL_CACHE_DIRandZIG_LOCAL_CACHE_DIRat.zig-cache..zig-cacheitself withactions/cache/restoreandactions/cache/save, under a fixed key: Zig version, job, OS, arch, and the hash of everybuild.zig.zon, taken before anything is unpacked.Windows build (fizzy backend, cross-compiled)still computed its key inline, the bug the test job's comment already described. Restore asked ford259c36b…and save wrotea0d09007…, so it missed every time (run 37786098520: "Cache miss"). It now takes its key from a step, like the other jobs.What a warm run keeps, and what it doesn't:
HttpConnectionClosing), the C libraries (SDL3 ×5, freetype, tree-sitter), and the build tools.build.zig.zon, Zig or the runner OS changes.Not touched:
web.yml'sbuildjob also uses setup-zig's caching. Its entries stay around 264 MB, so it doesn't hit the limit. It could move to the same scheme later.SDK impact
Verified
use-cache: false) → restore → … → save, with save gated onsuccess() && cache-hit != 'true'. No setup-zig cache inputs remain.main's first run is cold once and savesmain's copies, which every PR then restores. The oldsetup-zig-cache-v2-*entries go unused and age out after 7 days, or sooner under the 10 GB limit.Follow-ups
web.ymlto the same scheme if its cache ever grows.🤖 Generated with Claude Code