From a789cb6669272ef672d7bb5705b04bb9e94c5d13 Mon Sep 17 00:00:00 2001 From: Wesley van Tilburg Date: Sun, 27 Sep 2026 20:03:12 +0200 Subject: [PATCH] ci: prune old container registry tags too Add prune-registry.sh: keeps the moving tag and newest versioned tag per distro plus their cosign signature tags, deletes the rest via the Gitea packages API. Wire it into the prune job (uses REGISTRY_TOKEN). --- .gitea/workflows/build.yaml | 12 ++++++- prune-registry.sh | 64 +++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 prune-registry.sh diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 9ed7a35..add4905 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -135,10 +135,20 @@ jobs: GITEA_REPO: Misthios/bootc-images steps: - name: Install tools - run: dnf install -y nodejs jq curl + run: dnf install -y nodejs jq curl skopeo - name: Checkout uses: actions/checkout@v4 - name: Prune old releases env: RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} run: ./prune-releases.sh fedora-cosmic + - name: Prune old registry tags + env: + REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }} + REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + set -xeuo pipefail + authfile=/tmp/prune-auth.json + echo "${REGISTRY_TOKEN}" | skopeo login -u "${REGISTRY_USERNAME}" \ + --password-stdin --authfile "${authfile}" git.plabble.org + AUTHFILE="${authfile}" ./prune-registry.sh fedora-cosmic Misthios 44 rawhide diff --git a/prune-registry.sh b/prune-registry.sh new file mode 100644 index 0000000..862fbe5 --- /dev/null +++ b/prune-registry.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Prune old container image versions (tags) for an image in the Gitea registry. +# +# Keeps the moving tag (e.g. "44") and the newest versioned tag per distro, +# plus the cosign signature tag (sha256-.sig) for each kept image. +# +# Usage: +# REGISTRY_TOKEN= REGISTRY_USERNAME= \ +# ./prune-registry.sh [image] [owner] [distro...] +set -euo pipefail + +IMAGE="${1:-fedora-cosmic}"; shift || true +OWNER="${1:-Misthios}"; shift || true +DISTROS=("$@"); [[ ${#DISTROS[@]} -gt 0 ]] || DISTROS=(44 rawhide) + +GITEA_URL="${GITEA_URL:-https://git.plabble.org}" +REGISTRY_HOST="${REGISTRY_HOST:-$(printf '%s' "${GITEA_URL}" | sed -E 's#https?://##')}" +TOKEN="${REGISTRY_TOKEN:?REGISTRY_TOKEN (write:package) is required}" +AUTHFILE="${AUTHFILE:-${HOME}/.docker/config.json}" +API="${GITEA_URL%/}/api/v1/packages/${OWNER}/container/${IMAGE}" +IMAGE_REF="${REGISTRY_HOST}/${OWNER}/${IMAGE}" + +# Collect all versions (paginated). +versions="" +page=1 +while :; do + page_json="$(curl -fsSL -H "Authorization: token ${TOKEN}" \ + "${API}?limit=50&page=${page}")" || break + [[ "$(jq 'length' <<< "${page_json}")" -eq 0 ]] && break + versions+="$(jq -r '.[].version' <<< "${page_json}")"$'\n' + page=$((page + 1)) + [[ "${page}" -gt 40 ]] && break +done + +# Decide what to keep. +declare -A keep=() +for d in "${DISTROS[@]}"; do + keep["${d}"]=1 + newest="$(grep -E "^${d}\.[0-9]+\.[0-9]+$" <<< "${versions}" \ + | sort -t. -k2,2n -k3,3n | tail -1)" + [[ -n "${newest}" ]] && keep["${newest}"]=1 +done + +# Keep the cosign signature of each kept image tag. +for tag in "${!keep[@]}"; do + [[ "${tag}" == sha256-* ]] && continue + digest="$(skopeo inspect --authfile "${AUTHFILE}" --format '{{.Digest}}' \ + "docker://${IMAGE_REF}:${tag}" 2>/dev/null || true)" + [[ -n "${digest}" ]] && keep["sha256-${digest#sha256:}.sig"]=1 +done + +# Delete everything else. +while IFS= read -r v; do + [[ -z "${v}" ]] && continue + if [[ -n "${keep[${v}]:-}" ]]; then + echo "keep ${v}" + else + echo "remove ${v}" + curl -fsSL -X DELETE -H "Authorization: token ${TOKEN}" \ + "${API}/${v}" >/dev/null || echo " (failed to delete ${v})" + fi +done <<< "${versions}" + +echo "Pruned ${IMAGE} registry versions."