Skip to content

Prune superseded build caches on main - #383

Draft
gmarzot wants to merge 1 commit into
mainfrom
ci/prune-dep-caches
Draft

Prune superseded build caches on main#383
gmarzot wants to merge 1 commit into
mainfrom
ci/prune-dep-caches

Conversation

@gmarzot

@gmarzot gmarzot commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Draft — the numbers are measured, but this deletes caches, so it wants a look
before it runs.

Implements #381, and covers one thing that issue missed.

What accumulates

Both cache kinds mint a new entry per run rather than replacing one:

  • dep caches key on hashFiles('build/deps/github_hashes/**'), so every pin
    change makes a fresh ~1.3 GB entry per platform
  • ccache-action keys on a timestamp, so every run makes a fresh ~500 MB
    entry per lane. max-size: 500M bounds each entry, not how many exist

#381 only described the dep half. The ccache half is about the same size.

Measured effect

Against the live cache list for main (36 entries, 25.7 GB), keeping the newest
generation of each family selects 16 entries, 12.5 GB:

 8 ccache generations   ~3.9 GB   (one per lane, previous run)
 8 dep generations      ~8.7 GB   (one per platform, previous pin)

That takes the repo from 25.7 GB to 13.5 GB.

It does not get us under the limit

13.5 GB is still above GitHub's 10 GB, so eviction continues, just more slowly.
Closing the rest needs a policy call rather than more pruning — the candidates are
dropping dep caches for the sanitizer publish lanes (~2.6 GB), lowering ccache
max-size, or caching fewer publish platforms. Worth deciding separately; this
change is worth having either way.

How it works

A prune-caches job after build and publish, main only, actions: write.
It runs after those jobs so this run's caches are already saved and are the
generation kept. if: always() so a red build still gets pruned — a failed run
should not also leave the budget blown.

Family is the key minus its varying suffix, handling both shapes.

Verifying

gh cache delete cannot be rehearsed, but everything up to it was run against
live data:

  • the jq extracted verbatim from the workflow selects 16 entries / 12,507 MB,
    identical to the prototype
  • the selection is exactly one superseded generation per family — no newest
    generation and no unrecognized key is ever chosen
  • the IFS=$'\t' read loop parses all 16 rows and totals correctly
  • the heredoc terminator resolves to column 0 after YAML block-scalar parsing

The first real run should log ==> freed 12507 MB or close to it, and the repo's
cache usage should drop to ~13.5 GB.


This change is Reviewable

Both cache kinds mint a new entry per run rather than replacing one: the dep key
hashes the pin files, and ccache-action keys on a timestamp. Nothing removes the
superseded generation, so the repo sits at 25.7 GB against GitHub's 10 GB limit
and main's caches are the ones evicted, leaving PR jobs with nothing to restore.

Keeps the newest generation of each cache family after build and publish have
saved this run's. Measured against the current cache list: 16 entries, 12.5 GB.

Refs #381
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