Skip to content

Cleanup Interim Images #4

Cleanup Interim Images

Cleanup Interim Images #4

name: Cleanup Interim Images
# Deletes GHCR package versions whose tags are exclusively build-* (ephemeral
# per-commit images). Versions carrying any other tag (v*, edge, latest, etc.)
# are never touched. Runs weekly and can be triggered manually.
on:
schedule:
- cron: '0 8 * * 1' # Monday 08:00 UTC
workflow_dispatch:
# Serialise with docker-publish to avoid deleting a build-* image that a
# concurrent release promotion is about to resolve. cancel-in-progress: false
# makes cleanup wait rather than be killed.
concurrency:
group: docker-refs/heads/main
cancel-in-progress: false
permissions:
contents: read
packages: write
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Delete stale build-* package versions
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
OWNER="${{ github.repository_owner }}"
PACKAGE="${{ github.event.repository.name }}"
DELETED=0
KEPT=0
echo "Fetching package versions for ${OWNER}/${PACKAGE}..."
# Collect all versions into a temp file (handles pagination via --paginate)
gh api \
-H "Accept: application/vnd.github+json" \
"/users/${OWNER}/packages/container/${PACKAGE}/versions" \
--paginate > /tmp/versions.json
TOTAL=$(jq 'length' /tmp/versions.json)
echo "Found ${TOTAL} total package versions."
echo ""
jq -c '.[]' /tmp/versions.json | while read -r version; do
VERSION_ID=$(echo "$version" | jq -r '.id')
TAGS=$(echo "$version" | jq -r '.metadata.container.tags // [] | .[]')
# Skip untagged versions — never delete them (likely referenced by a manifest list)
if [ -z "$TAGS" ]; then
echo "KEEP [${VERSION_ID}] (untagged)"
continue
fi
TAG_LIST=$(echo "$TAGS" | tr '\n' ' ' | sed 's/ $//')
# Guard: keep if ANY tag does not match build-[0-9a-f]+
PROTECTED=false
while IFS= read -r tag; do
if [[ ! "$tag" =~ ^build-[0-9a-f]+$ ]]; then
PROTECTED=true
break
fi
done <<< "$TAGS"
if [ "$PROTECTED" = true ]; then
echo "KEEP [${VERSION_ID}] tags: ${TAG_LIST}"
else
echo "DELETE [${VERSION_ID}] tags: ${TAG_LIST}"
gh api \
--method DELETE \
-H "Accept: application/vnd.github+json" \
"/users/${OWNER}/packages/container/${PACKAGE}/versions/${VERSION_ID}"
fi
done
echo ""
echo "Cleanup complete."