- All playbooks
- Caching and setup
- Persist compiler output between runs
Persist compiler output between runs
Restore compatible compiler outputs and intermediate objects instead of recompiling unchanged inputs.
How companies used this technique
Read what each company changed and follow the original sources.
Cache the cross-compile producer’s objects
Codex's archive refactor moved the Windows ARM64 build onto a Windows x64 producer and turned on sccache for it, keying the producer's caches by the archive runner so the cross-compile reuses the Windows x64 cache.
sccache on for the Windows ARM64 archive producer Source
- Use it when
- One producer job compiles the same Rust or C++ inputs on every run before handing test binaries to native runners.
- Before applying it
- Compiler caches need the toolchain, target and flags in their identity, and trusted writers only. Cached compilation leaves native test execution in place.
Persist the compiler cache and warm it from the default branch
Ramp's CLI release workflow compiles the Python CLI to native binaries with Nuitka on every version tag. Ramp rooted Nuitka's caches (ccache on Linux and macOS, clcache on Windows) in the workspace through NUITKA_CACHE_DIR and saved them with actions/cache, keyed on the lockfile with restore prefixes. Caches are scoped per ref, so a new release tag starts from the default branch's caches and shares nothing with other tags; the workflow therefore also runs on every push to main to warm the cache; those runs build but skip packaging, artifact upload and the release jobs. A rerun of the same tag can also reuse that tag's own cache.
In the commit Release v0.2.26, the release workflow restores the Nuitka compiler cache on every build and warms it on each push to main. Source
The commit's workflow comments describe the change; the quote is from the diff. GitHub's cache rules let a run restore caches from its own ref and the default branch, so the quoted comment is narrower than that rule.
- Use it when
- A build job compiles the same native outputs from scratch on every run, and release builds run on tags.
- Before applying it
- A new tag build starts from the default branch's caches, so the warming run on main must use the same cache key prefix as the tag build.
Company Playbooks
- Read Anthropic’s playbookRun only affected tests
- Read DoorDash’s playbookRun build and test in parallel, sharded across CI agents
- Read Linear’s playbookBenchmark the same job on faster hardware
- Read Mastra’s playbookStarSling runners for the slowest test workflow
- Read OpenAI’s playbookRank CI fixes by the minutes they save
- Read Ramp’s playbookMove a CPU-bound test suite to a faster CPU
- Read Shopify’s playbookLet an agent iterate against one CI metric
- Read Spotify’s playbookBuild arm64 on native arm64 runners
- Read Stripe’s playbookRun only the tests a change can reach
- Read Uber’s playbookBuild the merge-queue speculations most likely to be needed