Skip to content

ci: prune superseded TokenSpeed CI images from GHCR - #2431

Merged
slin1237 merged 1 commit into
mainfrom
ci/prune-tokenspeed-images
Sep 5, 2026
Merged

ci: prune superseded TokenSpeed CI images from GHCR#2431
slin1237 merged 1 commit into
mainfrom
ci/prune-tokenspeed-images

Conversation

@slin1237

@slin1237 slin1237 commented Sep 5, 2026

Copy link
Copy Markdown
Member

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 + install
scripts). 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:

- name: Clean up local images
  run: docker rmi "$IMAGE" || true

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:

ci-tokenspeed-7cd7ca0b3028-0d355a7fe763   8.15 GB
ci-tokenspeed-7cd7ca0b3028-ac04a7866b6f   8.15 GB
ci-tokenspeed-7cd7ca0b3028-ac10053bdda6   8.15 GB

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:

  • A superseded tag cannot be computed by any future run, so nothing can ask
    for it.
  • A run that resolved a tag before it was deleted degrades rather than breaks.
    ci_fetch_tokenspeed_prebuilt.sh is explicitly tolerant — a failed pull logs
    lane will build from source and 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:

  • A version is only touched if every one of its tags starts with
    ci-tokenspeed-. The nightly-* and release images share this package and
    are never candidates.
  • The tag the lanes are resolving right now is kept regardless of age.

The job runs on the CPU pool rather than the docker pool, because that is where
the gh CLI is already in use. It has no if: condition, so it also runs on
the 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 unresolvable
tag, a failed listing, a rejected delete: each logs and returns success.

Changes

  • scripts/ci_prune_tokenspeed_images.sh (new): lists the container package's
    versions, keeps the newest TOKENSPEED_IMAGE_KEEP (default 2) plus the
    current tag, deletes the remaining ci-tokenspeed-* versions. DRY_RUN=1
    lists without deleting.
  • .github/workflows/ci-tokenspeed-image.yml: new prune job depending on
    build-and-push, plus a note about retention in the header.

Not included: the same package holds 192 nightly-* tags, which is a much
bigger 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 -n passes on the new script and check-yaml passes on the workflow.

Ran the script against a stubbed gh returning a canned package listing (four
ci-tokenspeed-* versions, one nightly-*, one release version tagged
1.10.1,latest, one version tagged both ci-tokenspeed-* and something else,
and one untagged version):

Case Result
default KEEP=2 kept the 2 newest, deleted the 2 oldest
KEEP=1 kept the newest, deleted 3
current tag is the oldest version kept the newest and the current, deleted 2
KEEP=abc, KEEP=0 skipped without deleting anything
every DELETE returns 403 warned per version, exit 0
no ci-tokenspeed-* versions clean no-op

In every case the nightly-*, release, mixed-tag, and untagged versions were
never selected.

Against the real registry with a token lacking read:packages, the listing
403s and the script logs listing package versions failed; skipping and exits
0 — 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 fmt passes (n/a, no Rust changes)
  • cargo clippy --all-targets --all-features -- -D warnings passes (n/a, no Rust changes)
  • (Optional) Documentation updated
  • (Optional) Please join us on Slack #sig-smg to discuss, review, and merge PRs

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>
@github-actions github-actions Bot added the ci CI/CD configuration changes label Sep 5, 2026
@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 7677b98e-6242-4d46-8ac4-2c1e2c85aa1a

📥 Commits

Reviewing files that changed from the base of the PR and between 38b284c and 687e995.

📒 Files selected for processing (2)
  • .github/workflows/ci-tokenspeed-image.yml
  • scripts/ci_prune_tokenspeed_images.sh

📝 Summary

Summary by CodeRabbit

  • Chores

    • Added automated cleanup for superseded TokenSpeed container images.
    • Retains the current image and the newest configured versions while removing older versions.
    • Cleanup runs after successful image builds and continues safely if configuration or tooling is unavailable.
    • Added dry-run support to preview cleanup actions without deleting images.
  • Documentation

    • Documented the retention behavior for content-addressed TokenSpeed image tags.

Walkthrough

The 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.

Changes

TokenSpeed image retention

Layer / File(s) Summary
Image pruning logic
scripts/ci_prune_tokenspeed_images.sh
The script validates configuration, filters and sorts TokenSpeed image versions, preserves required tags, supports dry runs, deletes older versions, and records optional step-summary results.
Workflow pruning integration
.github/workflows/ci-tokenspeed-image.yml
The workflow documents retention behavior and runs the pruning script after build-and-push with GH_TOKEN on the CPU runner pool.

Estimated code review effort: 3 (Moderate) | ~20 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/prune-tokenspeed-images

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 @coderabbitai help to get the list of available commands.

@slin1237
slin1237 merged commit 5d7342b into main Sep 5, 2026
10 of 13 checks passed
@slin1237
slin1237 deleted the ci/prune-tokenspeed-images branch September 5, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI/CD configuration changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant