ci: prune superseded TokenSpeed CI images from GHCR - #2431
Merged
Conversation
The prebuilt TokenSpeed image is tagged with a hash of its own inputs, so bumping the engine ref or the image tooling always produces a new tag and leaves the old one behind. Nothing can ever pull a superseded tag again, and nothing deletes it: the workflow's only cleanup is a docker rmi that frees disk on the build runner. Three of them have accumulated at ~8 GB each. Add a prune job that keeps the newest few images and deletes the rest. It runs on every image workflow run, including the no-op runs that find the tag already present, so the backlog clears on the next merge. Keeping more than one image is only about speed. A run that resolved the previous tag before the prune still pulls it instead of falling back to the source build, and a run that cannot pull falls back rather than failing, so the number is a tuning knob and not a correctness one. Only versions whose tags all carry the ci-tokenspeed- prefix are eligible; the nightly and release images share the package and are left alone. Every failure path logs and returns success, because cleanup must never fail a publish. Signed-off-by: Simo Lin <25425177+slin1237@users.noreply.github.com>
slin1237
requested review from
CatherineSue,
XinyueZhang369,
gongwei-130 and
key4ng
as code owners
September 5, 2026 16:16
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (2)
📝 SummarySummary by CodeRabbit
WalkthroughThe workflow now runs a tolerant GHCR cleanup script after TokenSpeed image builds. The script preserves the current tag and configured recent versions, then removes older superseded versions. ChangesTokenSpeed image retention
Estimated code review effort: 3 (Moderate) | ~20 minutes ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Your free Security trial is over. An organization admin can upgrade to Advanced for continuous pull request security review or dismiss this notice. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Problem
The prebuilt TokenSpeed CI image is tagged with a hash of its own inputs
(
scripts/ci_tokenspeed_image_tag.sh: engine ref + Dockerfile + installscripts). Bumping any of those produces a new tag, and the old one becomes
unreachable — no CI run will ever compute it again.
Nothing deletes it. The only cleanup in the workflow today is:
which frees disk on the build runner and does nothing to the registry. So every
bump strands a full image. Three have piled up so far, all on the same engine
ref, one per tooling change:
The current tag makes four. Nothing is billed for this — the package is public
— but it grows by 8 GB every time we touch the image tooling, and it makes the
package listing hard to read.
Solution
Add a prune job to the image workflow that keeps the newest few
ci-tokenspeed-*images and deletes the rest.Deleting these is safe by construction:
for it.
ci_fetch_tokenspeed_prebuilt.shis explicitly tolerant — a failed pull logslane will build from sourceand the lane compiles TokenSpeed instead.So the retention count is a speed knob, not a correctness one. It defaults to
2, which keeps the previous image around until the next bump so in-flight runs
stay on the fast path.
Two guards on what is eligible:
ci-tokenspeed-. Thenightly-*and release images share this package andare never candidates.
The job runs on the CPU pool rather than the docker pool, because that is where
the
ghCLI is already in use. It has noif:condition, so it also runs onthe no-op workflow runs that find the tag already present — which is how the
existing backlog gets cleared without waiting for the next engine bump.
Cleanup never fails the publish it follows. A missing
gh, an unresolvabletag, a failed listing, a rejected delete: each logs and returns success.
Changes
scripts/ci_prune_tokenspeed_images.sh(new): lists the container package'sversions, keeps the newest
TOKENSPEED_IMAGE_KEEP(default 2) plus thecurrent tag, deletes the remaining
ci-tokenspeed-*versions.DRY_RUN=1lists without deleting.
.github/workflows/ci-tokenspeed-image.yml: newprunejob depending onbuild-and-push, plus a note about retention in the header.Not included: the same package holds 192
nightly-*tags, which is a muchbigger pile and a separate retention question — those are pullable by people
and by other workflows, so the reasoning that makes this prune safe does not
carry over.
Test Plan
bash -npasses on the new script andcheck-yamlpasses on the workflow.Ran the script against a stubbed
ghreturning a canned package listing (fourci-tokenspeed-*versions, onenightly-*, one release version tagged1.10.1,latest, one version tagged bothci-tokenspeed-*and something else,and one untagged version):
KEEP=2KEEP=1KEEP=abc,KEEP=0ci-tokenspeed-*versionsIn every case the
nightly-*, release, mixed-tag, and untagged versions werenever selected.
Against the real registry with a token lacking
read:packages, the listing403s and the script logs
listing package versions failed; skippingand exits0 — the tolerant path a restricted workflow token would take.
In CI, this workflow triggers on changes to itself, so merging runs it: the
build is skipped because the tag already exists, and the prune job should
report
kept 2, deleted 2.Checklist
cargo +nightly fmtpasses (n/a, no Rust changes)cargo clippy --all-targets --all-features -- -D warningspasses (n/a, no Rust changes)