diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index d6d93aa..8293595 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -7,7 +7,8 @@ on: push: branches: ["main"] schedule: - - cron: "0 4 * * *" + # Weekly, Mondays 04:00 UTC. + - cron: "0 4 * * 1" jobs: build: diff --git a/prune-releases.sh b/prune-releases.sh new file mode 100755 index 0000000..cde0191 --- /dev/null +++ b/prune-releases.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# Delete older Gitea releases (including their assets and git tags) for an +# image, keeping only the newest release per distro. +# +# Usage: RELEASE_TOKEN= ./prune-releases.sh [image] +# +# The token defaults to $RELEASE_TOKEN; GITEA_URL/GITEA_REPO match the workflow. +set -euo pipefail + +IMAGE="${1:-fedora-cosmic}" +GITEA_URL="${GITEA_URL:-https://git.plabble.org}" +GITEA_REPO="${GITEA_REPO:-Misthios/bootc-images}" +TOKEN="${RELEASE_TOKEN:-${GITHUB_TOKEN:-}}" + +[[ -n "${TOKEN}" ]] || { echo "RELEASE_TOKEN (write:repository) is required" >&2; exit 1; } +API="${GITEA_URL%/}/api/v1/repos/${GITEA_REPO}" + +# Collect matching releases (API returns newest first). +all="" +page=1 +while :; do + page_json="$(curl -fsSL -H "Authorization: token ${TOKEN}" \ + "${API}/releases?limit=50&page=${page}")" + [[ "$(jq 'length' <<< "${page_json}")" -eq 0 ]] && break + all+="$(jq -r --arg p "${IMAGE}-" \ + '.[] | select(.tag_name | startswith($p)) | "\(.tag_name)\t\(.id)"' \ + <<< "${page_json}")"$'\n' + page=$((page + 1)) + [[ "${page}" -gt 40 ]] && break +done + +# Tag shape: "-.." -> prefix "-". +# Keep the first (newest) release seen per prefix, delete the rest. +seen="" +while IFS=$'\t' read -r tag id; do + [[ -z "${tag}" ]] && continue + prefix="${tag%.*.*}" + if grep -qxF "${prefix}" <<< "${seen}"; then + echo "removing ${tag}" + curl -fsSL -X DELETE -H "Authorization: token ${TOKEN}" \ + "${API}/releases/${id}" >/dev/null || true + curl -fsSL -X DELETE -H "Authorization: token ${TOKEN}" \ + "${API}/tags/${tag}" >/dev/null || true + else + seen+="${prefix}"$'\n' + echo "keeping ${tag}" + fi +done <<< "${all}" + +echo "Pruned ${IMAGE} releases (kept newest per distro)." diff --git a/release.sh b/release.sh index 80ab7a6..3fcfb93 100755 --- a/release.sh +++ b/release.sh @@ -156,3 +156,29 @@ curl -fsSL -X POST \ "${API}/releases/${release_id}/assets?name=${ASSET_NAME}" echo "Published release ${RELEASE_TAG}." + +# --- prune older releases (and their assets/tags) for this image/distro ----- +echo "Pruning older ${IMAGE} ${DISTRO} releases ..." +old_releases="" +page=1 +while :; do + page_json="$(curl -fsSL -H "Authorization: token ${TOKEN}" \ + "${API}/releases?limit=50&page=${page}")" + [[ "$(jq 'length' <<< "${page_json}")" -eq 0 ]] && break + old_releases+="$(jq -r --arg prefix "${IMAGE}-${DISTRO}." --arg keep "${release_id}" \ + '.[] | select(.tag_name | startswith($prefix)) | select((.id | tostring) != $keep) | "\(.id)\t\(.tag_name)"' \ + <<< "${page_json}")"$'\n' + page=$((page + 1)) + [[ "${page}" -gt 20 ]] && break +done + +while IFS=$'\t' read -r old_id old_tag; do + [[ -z "${old_id}" ]] && continue + echo " removing release ${old_tag}" + curl -fsSL -X DELETE -H "Authorization: token ${TOKEN}" \ + "${API}/releases/${old_id}" >/dev/null || true + curl -fsSL -X DELETE -H "Authorization: token ${TOKEN}" \ + "${API}/tags/${old_tag}" >/dev/null || true +done <<< "${old_releases}" + +echo "Done."