Skip to content

ci: cache Rust builds in the desktop and iOS checks, and the Windows Ghostty VT build - #76

Merged
jamesyong-42 merged 4 commits into
mainfrom
ci/rust-cache
Oct 25, 2026
Merged

jamesyong-42 merged 4 commits into
mainfrom
ci/rust-cache

Conversation

@jamesyong-42

@jamesyong-42 jamesyong-42 commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Every PR's required checks (verify, windows) compiled the whole Rust dependency graph from scratch, several times per job. windows also rebuilt the pinned Ghostty VT library from source on every run. This PR caches both, so a PR's required checks finish in about 10 minutes instead of about 14.

Measured on dispatched runs of this branch

Job Before (PR #73) Cold cache Warm cache
verify (macOS) 832 s 710 s 409–443 s
windows 738 s 849–1080 s 578 s (Ghostty VT build skipped)
minimum-rust 81 s 70–94 s 40–43 s
iOS build:apple-native step 152 s 148–213 s 37 s

Windows runners vary by about ±150 s from run to run, so read single numbers loosely. The Ghostty VT build alone takes 107–174 s, and a cache hit skips it.

What changes

  1. Rust dependency cache. Swatinem/rust-cache@v2 runs in verify, windows, minimum-rust and iOS validate-package-manifests.
    • Only non-PR events save: a push to main, the weekly schedule, or a dispatch. PRs only read main's cache, so they can't evict it.
    • Workspace crates always rebuild, and cache-bin: false keeps ~/.cargo/bin out.
  2. Stable keys for pinned toolchains. minimum-rust and the iOS job uninstall the image's own stable before the cache step.
    • rust-cache keys on every installed toolchain, and the image's stable moved from 1.99.0 to 1.99.1 between two of these runs. The iOS cache missed because of that, and after this fix it hits.
    • verify and windows install stable themselves and already hash exactly one toolchain.
  3. Windows Ghostty VT cache. The source-built install tree, 4 MB, is cached.
    • The key covers the lock, the patches, the build scripts and the runner image (ImageOS and ImageVersion).
    • A new image, which can move MSVC or the Windows SDK, rebuilds from source, as does any pin or recipe change.
    • Restore and save are split, so PRs only read.

Unchanged: publish-release and the Apple publication build never use these caches, so a published binary is always built from scratch.

Storage: about 1.4 GB on main: verify 489 MB, windows 521 MB, iOS 208 MB, minimum-rust 141 MB, VT 4 MB. The repository's limit is 10 GB.

After merge: main's next push saves the caches, and PRs benefit from then on. Until then, PR runs behave like cold runs.

Merging: merging #73, this PR, #74 and #75 onto main in sequence is conflict-free (checked with git merge-tree), and the combined workflows parse.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

jamesyong-42 and others added 4 commits October 24, 2026 22:07
…dependencies — the required checks stop compiling the dependency graph from scratch

- No job cached Rust builds. ci:desktop compiles the dependency graph cold several times per job:
  cargo check and clippy, cargo test, the FFI parity probe, and the release build for the soak.
  On PR #73, verify ran 832 s and windows 738 s, and those two bound every PR's wall-clock.
- Swatinem/rust-cache@v2 now runs after each toolchain step. Its key is the job, OS, rustc and the
  lockfile. A moved lockfile restores the newest cache for the same job and rustc. Workspace
  crates are not cached and always rebuild, so what is tested is what is checked out.
- save-if: only non-pull_request events save (a push to main, the weekly schedule, a dispatch).
  Pull requests read main's cache and never write their own, so the repository's cache holds one
  entry per job instead of one per PR.
- cache-bin: false keeps ~/.cargo/bin out, so the toolchain that dtolnay/rust-toolchain installed
  is the one that runs.
- Unchanged:
  - publish-release builds and tests with no cache, so a published binary never comes from one;
  - the iOS and Apple artifact workflows are untouched.
- Verified here: the workflow parses, with the cache step after each toolchain step. Cold and warm
  timings come from dispatched runs of this branch; see the PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s of its three Apple targets — build:apple-native stops compiling them from scratch

- build:apple-native runs `cargo build --release -p ghosttea-apple-ffi` for aarch64-apple-darwin,
  aarch64-apple-ios and aarch64-apple-ios-sim. It took 152 s on PR #73 (run 40156639614) and
  133-163 s on earlier runs, nearly all of it compiling the same dependency graph three times.
- Swatinem/rust-cache@v2 after the 1.97.1 toolchain step, with the desktop gates' policy:
  - only non-pull_request events save;
  - workspace crates are not cached;
  - ~/.cargo/bin stays out.
- The publication build (build-candidate in ghosttea-apple-native-artifact.yml) is unchanged and
  still compiles everything from scratch.
- Verified here: the workflow parses with the cache step after the toolchain. Cold and warm timings
  come from dispatched runs of this branch; see the PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ary while the pin, scripts and runner image are unchanged — about three minutes less on the slowest required check

- With the Rust cache warm, windows became the slowest required check: 723 s against verify's
  409 s (run 40159719334). Its source build of the pinned libghostty-vt took 165 s of that; it
  was 107-174 s on earlier runs.
- The key hashes native/ghostty.lock.json, native/patches, and the bootstrap, build and target
  scripts, with the runner's ImageOS and ImageVersion.
  - A new image can move MSVC or the Windows SDK, so it rebuilds from source, as does any change
    to what the build reads.
  - The source build therefore still runs whenever the pin, a patch or the recipe changes, and at
    least once per runner image on main.
- Only native/build/ghostty/x86_64-pc-windows-msvc/install is cached. That is the tree
  ghosttea-vt-sys's build.rs links (Prefix::Repository); Zig's cache and global directories stay
  out.
- actions/cache/restore and actions/cache/save are split so that, as with the Rust cache, pull
  requests only read it. The bootstrap still runs: ci:desktop's FFI test syncs fonts from
  native/vendor/ghostty.
- Unchanged: verify, which links the downloaded verified artifact, and publish-release's
  validate-windows, which still builds from source with no cache.
- Verified here:
  - the workflow parses with the steps and conditions above;
  - the key step passes `bash -n`, and run locally it yields
    ghostty-vt-x86_64-pc-windows-msvc-v1-<image>-<inputs digest>;
  - actions/cache/restore@v6 and actions/cache/save@v6 exist.
  Cold and warm timings come from dispatched runs of this branch; see the PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st-cache keys on it — an image update no longer empties their cache

- rust-cache hashes `rustc -vV` of every toolchain `rustup toolchain list` reports, and the runner
  images ship their own stable beside the one a job pins:
  - minimum-rust's key covered 1.88.0 and the macos-15 image's 1.98.1;
  - validate-package-manifests' key covered 1.97.1 and the macos-26 image's stable.
- The second iOS measurement run therefore missed the cache the first had just saved. The image's
  stable moved from 1.99.0 to 1.99.1 between them (runs 40158922303 and 40159882964), so the
  environment hash went from 2b482aa2 to 12ecd235.
- Both jobs now uninstall every toolchain except the one dtolnay/rust-toolchain installed, which
  is rustup's default, so nothing else ran on them. A missing toolchain name fails the step
  instead of uninstalling everything. verify and windows install stable itself and already hash
  exactly one toolchain.
- Verified here: both workflows parse with the step between the toolchain and the cache. Against a
  stub rustup listing 1.97.1 and stable, the step uninstalls only stable; with an empty name it
  exits 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jamesyong-42
jamesyong-42 merged commit 9a83443 into main Oct 25, 2026
6 checks passed
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