#!/usr/bin/env bash set -Eeuo pipefail separator() { printf '\n%s\n' '==================================================' } section() { separator printf '%s\n' "$1" printf '%s\n' '--------------------------------------------------' } info() { printf '[INFO] %s\n' "$1" } success() { printf '[OK] %s\n' "$1" } warn() { printf '[WARN] %s\n' "$1" } fail() { printf '[ERR] %s\n' "$1" >&2 } is_empty_or_null() { [ -z "${1:-}" ] || [ "${1:-}" = "null" ] } require_value() { local name="$1" local value="$2" info "$name=$value" if is_empty_or_null "$value"; then fail "$name is required" exit 1 fi } require_integer() { local name="$1" local value="$2" if ! [[ "$value" =~ ^[0-9]+$ ]]; then fail "$name must be a non-negative integer" exit 1 fi } section "參數檢查" require_value "GITEA_SERVER_URL" "$GITEA_SERVER_URL" require_value "GITEA_REPOSITORY" "$GITEA_REPOSITORY" require_value "KEEP_COUNT" "$KEEP_COUNT" require_integer "KEEP_COUNT" "$KEEP_COUNT" if is_empty_or_null "${RUNNER_TOKEN:-}"; then warn "RUNNER_TOKEN is empty; release API calls will be anonymous" else info "RUNNER_TOKEN=[redacted]" fi release_api_url="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/releases" auth_header=() if ! is_empty_or_null "${RUNNER_TOKEN:-}"; then auth_header=(-H "Authorization: token $RUNNER_TOKEN") fi section "取得成品資訊" info "GET $release_api_url" release_json='[]' page=1 while :; do page_url="$release_api_url?page=$page" page_json="$(curl -fsS "${auth_header[@]}" "$page_url")" if [ "$(jq 'length' <<<"$page_json")" -eq 0 ]; then break fi release_json="$(jq -s 'add' <<<"$release_json"$'\n'"$page_json")" page=$((page + 1)) done release_json="$(jq -e 'sort_by(.created_at) | reverse' <<<"$release_json")" release_count="$(jq 'length' <<<"$release_json")" info "RELEASE_COUNT=$release_count" info "KEEP_COUNT=$KEEP_COUNT" if [ "$release_count" -le "$KEEP_COUNT" ]; then success "沒有需要清理的舊版本成品" exit 0 fi section "刪除舊版本成品" release_to_delete="$(jq -c ".[$KEEP_COUNT:]" <<<"$release_json")" while IFS= read -r release_item; do [ -z "$release_item" ] && continue release_id="$(jq -r '.id' <<<"$release_item")" release_tag="$(jq -r '.tag_name' <<<"$release_item")" release_name="$(jq -r '.name' <<<"$release_item")" if is_empty_or_null "$release_id"; then warn "略過沒有 id 的成品: $release_tag ($release_name)" continue fi delete_url="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/releases/$release_id" info "DELETE $release_tag ($release_name)" delete_code="$(curl -sS -o /dev/null -w "%{http_code}" -X DELETE "${auth_header[@]}" "$delete_url")" if [ "$delete_code" -eq 204 ]; then success "成功刪除: $release_tag ($release_name)" else fail "刪除失敗: $release_tag ($release_name), HTTP $delete_code" fi done < <(jq -c '.[]' <<<"$release_to_delete") separator