prune-ci-images

Audit and batch-delete stale GHCR container image versions with human review.

4.2k|179|Updated May 24, 2022
One-click install
npx skills add https://github.com/posit-dev/positron --skill prune-ci-images
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: prune-ci-images
Source: https://github.com/posit-dev/positron/tree/main/.claude/skills/prune-ci-images
Command: npx skills add https://github.com/posit-dev/positron --skill prune-ci-images

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) components.

What problem does it solve?

Old CI container images accumulate in the GitHub Container Registry, cluttering the package list and making it hard to tell which versions are still load-bearing. Deleting them blindly is dangerous: untagged per-arch manifests look like garbage but are referenced by live multi-arch indexes, and removing them breaks tagged images.

Core Features & Use Cases

  • Read-only audit: Generates a markdown review list of every positron OS/postgres image version older than a cutoff (default 90 days), automatically excluding tags referenced in the repo and children of retained multi-arch indexes.
  • Fail-closed prune: Re-validates the reviewed list against live registry state before deleting, aborting on tag drift, newly in-use tags, unresolved manifests, or split multi-arch groups.
  • Package cleanup: Optionally deletes packages emptied down to their last tagged version, which GHCR refuses to remove at the version level.
  • Use Case: A maintainer wants to garbage-collect hundreds of stale positron-rocky8 and positron-postgres image versions without breaking any CI workflow that still pins an old tag.

Quick Start

Ask the assistant to audit old GHCR CI images older than 90 days and produce a review list for pruning.

Frequently Asked Questions about prune-ci-images

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I delete old GHCR container image versions safely?

Run ghcr-audit.sh to produce a markdown review list of versions older than the cutoff, have a human delete rows they want to keep, then run ghcr-prune.sh with --confirm. The prune step re-validates everything against the live registry and aborts on any drift.

How to clean up GitHub Container Registry packages with gh CLI?

Use the gh api endpoints for org packages: list versions, delete them by ID, and optionally delete whole packages. This skill wraps those calls in scripts that check tags, resolve multi-arch manifests, and require explicit confirmation before deleting.

Why does GHCR refuse to delete the last tagged version of a package?

GHCR blocks deletion of a package's final tagged version and reports it either as a last-tagged-version error or a misleading 5000-downloads message. The only way to clear it is a package-level delete, which ghcr-delete-packages.sh handles as a separate approved step.

Can deleting untagged GHCR manifests break a tagged image?

Yes. Multi-arch builds push an index plus untagged per-arch manifests into the same package, and deleting those children breaks the tagged image. The audit resolves every retained index and protects its child digests, and the prune step re-derives this protection before deleting.

What permissions are needed to delete GitHub Packages versions?

The gh token needs read:packages for the audit and delete:packages for pruning, plus admin rights on the packages themselves. Org member read access alone is not sufficient to delete versions or packages.

What are the limitations of scanning a repo for in-use image tags?

The scan reads only the working tree and matches literal ghcr.io/owner/pkg:tag strings under .github/, docker/, test/, scripts/, and build/. Tags referenced only on other branches, assembled from variables at runtime, or living in external repos are invisible, so pass --protect-tag for those.