#!/usr/bin/env bash set -euo pipefail # ============================================================================= # Defaults (override via CLI flags) # ============================================================================= REGISTRY="https://git.motovaultpro.com" USERNAME="egullickson" TOKEN="" KEEP_TAG="latest" DRY_RUN=1 REPOS=( "egullickson/frontend" "egullickson/backend" ) # ============================================================================= need() { command -v "$1" >/dev/null || { echo "ERROR: missing dependency: $1"; exit 1; }; } need curl need jq usage() { cat </dev/null } purge_repo_keep_tag() { local repo="$1" echo "== Purging ${repo} (keep ${KEEP_TAG}) ==" local auth auth="$(auth_header_for_repo "$repo")" local json tags json="$(tags_list "$repo" "$auth")" tags="$(echo "$json" | jq -r '.tags[]?' | sort || true)" if [[ -z "$tags" ]]; then echo "No tags found." echo return 0 fi if ! echo "$tags" | grep -qx "${KEEP_TAG}"; then echo "WARN: No '${KEEP_TAG}' tag found; refusing to purge ${repo}." echo "$tags" | sed 's/^/ - /' echo return 0 fi local keep_digest keep_digest="$(digest_for_tag "$repo" "$KEEP_TAG" "$auth" || true)" if [[ -z "$keep_digest" ]]; then echo "ERROR: Could not resolve digest for ${repo}:${KEEP_TAG}" echo "Tip: curl -vI -H \"$auth\" ${REGISTRY}/v2/${repo}/manifests/${KEEP_TAG}" echo return 1 fi echo "${KEEP_TAG} digest: ${keep_digest}" # Collect digests referenced by non-KEEP_TAG tags (skipping those equal to keep_digest) local digests=() while read -r tag; do [[ -z "$tag" || "$tag" == "$KEEP_TAG" ]] && continue local d d="$(digest_for_tag "$repo" "$tag" "$auth" || true)" if [[ -z "$d" ]]; then echo "WARN: couldn't resolve digest for tag=${tag} (skipping)" continue fi if [[ "$d" == "$keep_digest" ]]; then echo "SKIP: tag=${tag} points to ${KEEP_TAG} digest (deleting would remove ${KEEP_TAG} too)" continue fi digests+=("$d") done <<< "$tags" if [[ "${#digests[@]}" -eq 0 ]]; then echo "Nothing to delete." echo return 0 fi echo "Will delete (deduped) manifest(s) (and all tags pointing to them)." printf '%s\n' "${digests[@]}" | sort -u | while read -r digest; do [[ -z "$digest" ]] && continue echo "Deleting digest: $digest" if ! delete_digest "$repo" "$digest" "$auth"; then echo "WARN: delete failed for $digest" fi done echo "Done." echo } for repo in "${REPOS[@]}"; do purge_repo_keep_tag "$repo" done echo "Complete."