Skip to content

Add GHCR pruning workflow that respects multi-arch manifests - #48

Merged
mtthwcmpbll merged 1 commit into
mainfrom
reef
Jul 25, 2026
Merged

Add GHCR pruning workflow that respects multi-arch manifests#48
mtthwcmpbll merged 1 commit into
mainfrom
reef

Conversation

@mtthwcmpbll

Copy link
Copy Markdown
Owner

Nothing in CI reclaimed package storage, so every release left intermediate builds behind in GHCR — 34 container versions across 6 builds, of which only 2 are releases.

The obvious fix (actions/delete-package-versions with delete-only-untagged-versions: true) is actively unsafe here: release.yml merges per-arch images with docker buildx imagetools create, so each release tag is an OCI index whose per-platform and attestation manifests appear in the packages API as untagged versions — deleting all untagged versions would break docker pull for latest, 0.0.2 and 0.0.1, which reference them directly.

This instead resolves the manifest graph from the registry and prunes in two passes: drop disposable commit-SHA dev builds, then recompute reachability against the survivors and delete only what nothing points to, with releases and latest protected by pattern and a keep_days floor for recent builds.

Runs manually with a dry_run toggle (default true) plus a weekly cron; verified in dry-run against the live package — 22 of 34 versions pruned, both releases and latest intact, all 8 of their referenced child manifests protected.

Note: if a real run 403s, GITHUB_TOKEN lacks delete rights on packages — add a classic PAT with delete:packages as a PACKAGES_TOKEN secret and the workflow will prefer it. That path is untested since testing it requires a live deletion.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HvwxjJxDn9eq4HaMz5mrEw

Nothing in CI reclaimed package storage, so every release left its
intermediate builds behind in GHCR.

The obvious fix — actions/delete-package-versions with
delete-only-untagged-versions — is unsafe here. release.yml publishes
per-arch images and merges them with `docker buildx imagetools create`,
so each release tag is an OCI index whose per-platform and attestation
manifests appear in the packages API as untagged versions. Deleting all
untagged versions would break `docker pull` for latest, 0.0.2 and 0.0.1,
which reference those manifests directly.

Instead, resolve the manifest graph from the registry and prune in two
passes: drop disposable commit-SHA dev builds, then recompute
reachability against the survivors and delete only what nothing points
to. Releases and latest are protected by pattern, with a keep_days floor
for recent builds.

Runs manually with a dry_run toggle (default true) plus a weekly cron.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvwxjJxDn9eq4HaMz5mrEw
@mtthwcmpbll
mtthwcmpbll merged commit a89c5c7 into main Jul 25, 2026
2 checks passed
@mtthwcmpbll
mtthwcmpbll deleted the reef branch July 25, 2026 23:17
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