Skip to content

CI: cache builds and run on every branch - #5

Closed
sachio222 wants to merge 3 commits into
mainfrom
ci-speed
Closed

sachio222 wants to merge 3 commits into
mainfrom
ci-speed

Conversation

@sachio222

@sachio222 sachio222 commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Every push to any branch now runs CI, so Windows test failures show up on the branch instead of on release day. Builds now hit their cache reliably. A whole run still takes about 32 minutes, because Windows spends 25 to 29 minutes running the tests themselves.

Run times

Minutes per job. Baseline is run 40445557572 on main, which restored a warm Swatinem cache. The first run on this branch started with an empty cache (40455857892), and the second restored it (40462778615).

Job Baseline First run Cached run
Test (windows-latest) 31.8 35.9 31.8
Windows: build the tests 3.1 10.4 2.1
Windows: run the tests 27.9 25.0 29.2
Build for Linux aarch64 18.5 19.4 17.7
Test (macos-15-intel) 9.9 10.9 7.4
Test (macos-14) 4.3 8.0 5.0
Test (ubuntu-24.04) 4.1 6.1 4.3
Release-style build 2.4 5.7 2.5
Format and clippy 0.6 4.8 0.7

On main, Windows sometimes found no cache and built for 17.3 minutes (run 40328135709). With line tables only, an empty-cache Windows build now takes 10.4 minutes.

Windows fails the same nine drop-path tests on this branch as on main. #4 fixes them.

What changed in ci.yml

  • Pushes to any branch run every job. A pull request from a branch in this repository skips its own run, because the push already tested the same commit. Pull requests from forks still run in full.
  • A newer push to a branch cancels the older run on that branch. Each commit on main keeps its own run.
  • actions/cache replaces Swatinem/rust-cache. The key names the job, the runner, rust-toolchain.toml and Cargo.lock, with a fallback to the newest cache for the same job, runner and toolchain. The old Windows key also hashed whichever Rust the runner image preinstalled, so it changed with image updates.
  • A job saves its cache only when no exact match exists and its build passed, so a failing test still leaves the build cached. Branches whose Cargo.lock matches main read main's cache and save nothing.
  • Before saving, cargo clean -p removes the workspace's own crates, which every commit rebuilds. A restored target/ over 4 GB is thrown away, so old dependency versions cannot pile up. Each job's cache is 231 to 302 MB, about 1.9 GB for all seven, against the 10 GB repository limit.
  • Test builds keep line tables only (CARGO_PROFILE_DEV_DEBUG=line-tables-only) and run with CARGO_INCREMENTAL=0. Tests build with --no-run first, so the log shows build time and test time as separate steps.
  • On the first push of a new branch, the crate age check compares with the commit where the branch left main. Before, it checked every crate again.

Operating systems, features, test commands and jobs are unchanged. sh scripts/workflow-check.sh .github/workflows/*.yml and sh scripts/workflow-check-test.sh pass.

Every push to any branch now runs CI, so a branch shows Windows test
failures before it reaches main. A pull request from a branch in this
repository skips its own run, since the push already ran on the same
commit; pull requests from forks still run in full. A newer push to a
branch cancels the older run, and every commit on main keeps its run.

Builds cache downloaded crates and target/ with actions/cache, keyed on
the job, the runner, rust-toolchain.toml and Cargo.lock. A job saves
only on a miss and only after its build passed, so failing tests still
leave the build cached. The workspace's own crates are removed before
saving, and a restored target/ over 4 GB is thrown away. This replaces
Swatinem/rust-cache, whose Windows key changed whenever the runner image
updated its preinstalled Rust, so Windows often built from nothing (17
minutes instead of 3).

Test builds keep line tables only for debug info, incremental builds
are off, and tests build with --no-run before they run, so the log
shows build and test time apart.

The crate age check on a new branch compares with the commit where the
branch left main instead of checking every crate again.
du fails on a missing target/ and the bash step runs with pipefail, so the first run on a cold cache stopped there. The step now counts a missing target/ as 0 MB.
@sachio222

Copy link
Copy Markdown
Owner Author

Merged to main from branch ci-cache, the same commits moved onto 0.6.1, with a timing test given more room.

@sachio222 sachio222 closed this Oct 27, 2026
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