Semantic Diff

#9279 Restore earlier CI caches when the dependencies change

8 commits

145df8dff46ed56a75c34047996393aae756292b..pr-9279

5d8175636 · cknitt + Claude · Nov 09, 2026, 13:53 UTC

Reuse CI caches across dependency changes and delete superseded ones

A change of the opam files missed every OPAM cache, so CI rebuilt the environments from scratch (9 to 16 minutes on master today, on every push of a pull request that changes them), and left the old ones behind: the repository's caches exceed the 10 GB limit, so live ones get evicted. The environment and build state of the previous dependencies are now restored and updated, and master deletes superseded generations when it saves. The coverage build state no longer changes key with every compiler commit.

014e1ea81 · cknitt + Claude · Nov 09, 2026, 14:16 UTC

Brace the prefix in the coverage build state key

$prefix6d99… named a variable that doesn't exist, so the key was empty and the coverage job failed to restore its build state.

4a1637f57 · cknitt + Claude · Nov 09, 2026, 14:17 UTC

Don't let opam rebuild a restored switch for its system packages

On Linux, opam took the packages that setup-linux-dependencies unpacks without dpkg for removed and recompiled all 64 packages of the restored switch (6 to 9 minutes); the fallback now skips system dependencies.

2cf79a96b · cknitt + Claude · Nov 09, 2026, 19:57 UTC

Grant build-compiler the permission to delete caches

Codex review: the job relied on the repository's default token permissions for the cache deletions of master pushes, which now fail instead of being ignored.

d965a5ee9 · cknitt + Claude · Nov 10, 2026, 14:52 UTC

Restore earlier OPAM environments for pull requests only and stop pruning

A restored environment is only ever added to, and master saved it under the new key: a pin dropped from the opam files, a removed dependency or a missed upgrade stayed in every later environment, and only a prefix bump recovered. Pushes now build a missing environment anew, and only pull requests restore an earlier one. The pruning of superseded caches is gone: GitHub evicts the least recently used caches first, which are those, and its errors could fail master builds. On a fallback, opam keeps the installed packages as they are and bypasses only the two system packages it misreads, so new system dependencies are still installed.

Review

  • Why keep the build state's fallback on master? dune rebuilds what the new dependencies change, so a restored state can't go stale.
3b8e0af7b · cknitt + Claude · Nov 10, 2026, 18:06 UTC

Unpin restored environments and resolve one job from scratch

Review fixes for the pull request fallback. Pins of earlier dependencies are dropped before the install, which pins what the opam files still pin; the OCaml 5.0 job never restores an earlier environment, so a dependency change still gets one fresh resolution before the merge; and Windows installs read the bash_env that ocaml/setup-ocaml writes. The depext bypass now applies to every install, and only environments resolved from scratch are saved. The build state keys no longer end in a hash of the opam files, so master keeps one state per job.

449b4bd01 · cknitt · Nov 10, 2026, 14:52 UTC

DO NOT MERGE: change an opam file to test the cache fallback

Dropped before merging; it makes this pull request's CI take the fallback path.

af15778cc · cknitt + Claude · Nov 10, 2026, 18:26 UTC

Drop the temporary opam change

It made this pull request's CI take the fallback path: the restored jobs set up OPAM in 35 to 61 seconds, the OCaml 5.0 job resolved from scratch.