unrelease.sh 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. RELEASE_NAME="${1:-}"
  4. GHCR_IMAGE="ghcr.io/olivetin/olivetin"
  5. DOCKERHUB_IMAGE="jamesread/olivetin"
  6. log() {
  7. echo "[unrelease] $*"
  8. }
  9. prompt_confirm() {
  10. local prompt="$1"
  11. local default="${2:-n}"
  12. if [[ "$default" == "y" ]]; then
  13. read -r -p "$prompt [Y/n] " reply
  14. else
  15. read -r -p "$prompt [y/N] " reply
  16. fi
  17. reply="${reply:-$default}"
  18. case "$(echo "$reply" | tr '[:upper:]' '[:lower:]')" in
  19. y|yes) return 0 ;;
  20. *) return 1 ;;
  21. esac
  22. }
  23. if [[ -z "$RELEASE_NAME" ]]; then
  24. echo "Usage: $0 <release_name>" >&2
  25. echo "Example: $0 3000.10.0" >&2
  26. exit 1
  27. fi
  28. log "Release to remove: $RELEASE_NAME"
  29. log "This will: 1) Delete GitHub release, 2) Delete GitHub tag, 3) Delete GHCR image tag, 4) Delete Docker Hub image tag"
  30. echo
  31. # --- GitHub release ---
  32. log "Step 1: Delete GitHub release '$RELEASE_NAME'"
  33. if prompt_confirm "Delete GitHub release?" "n"; then
  34. if err=$(gh release delete "$RELEASE_NAME" --yes 2>&1); then
  35. log "Deleted GitHub release."
  36. else
  37. log "Failed to delete GitHub release:" >&2
  38. echo "$err" | sed 's/^/[unrelease] /' >&2
  39. fi
  40. else
  41. log "Skipped GitHub release."
  42. fi
  43. echo
  44. # --- GitHub tag ---
  45. log "Step 2: Delete GitHub tag '$RELEASE_NAME'"
  46. if prompt_confirm "Delete GitHub tag?" "n"; then
  47. repo=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null) || repo="olivetin/olivetin"
  48. if err=$(gh api -X DELETE "repos/$repo/git/refs/tags/$RELEASE_NAME" 2>&1); then
  49. log "Deleted GitHub tag."
  50. else
  51. log "Failed to delete GitHub tag:" >&2
  52. echo "$err" | sed 's/^/[unrelease] /' >&2
  53. fi
  54. else
  55. log "Skipped GitHub tag."
  56. fi
  57. echo
  58. # --- GHCR ---
  59. log "Step 3: Delete GHCR image tag $GHCR_IMAGE:$RELEASE_NAME"
  60. if prompt_confirm "Delete GHCR container image version?" "n"; then
  61. list_err=$(gh api "orgs/olivetin/packages/container/olivetin/versions" --jq ".[] | select(.metadata.container.tags[]? == \"$RELEASE_NAME\") | .id" 2>&1) || true
  62. version_id=$(echo "$list_err" | head -1)
  63. if [[ -z "$version_id" || ! "$version_id" =~ ^[0-9]+$ ]]; then
  64. log "Could not resolve GHCR version for tag '$RELEASE_NAME' (need read:packages scope, or tag may not exist)." >&2
  65. if [[ "$list_err" == *"message"* ]]; then
  66. msg=$(echo "$list_err" | sed -n 's/.*"message":"\([^"]*\)".*/\1/p' | head -1)
  67. [[ -n "$msg" ]] && log " $msg" >&2
  68. fi
  69. else
  70. if err=$(gh api -X DELETE "orgs/olivetin/packages/container/olivetin/versions/$version_id" 2>&1); then
  71. log "Deleted GHCR version (id: $version_id)."
  72. else
  73. log "Failed to delete GHCR version:" >&2
  74. echo "$err" | sed 's/^/[unrelease] /' >&2
  75. fi
  76. fi
  77. else
  78. log "Skipped GHCR."
  79. fi
  80. echo
  81. # --- Docker Hub ---
  82. log "Step 4: Delete Docker Hub image tag $DOCKERHUB_IMAGE:$RELEASE_NAME"
  83. if prompt_confirm "Delete Docker Hub image tag? (requires DOCKERHUB_TOKEN)" "n"; then
  84. if [[ -z "${DOCKERHUB_TOKEN:-}" ]]; then
  85. log "DOCKERHUB_TOKEN is not set. Get a token from https://hub.docker.com/settings/security and run: DOCKERHUB_TOKEN=xxx $0 $RELEASE_NAME" >&2
  86. log "Skipped Docker Hub."
  87. else
  88. status=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
  89. -H "Authorization: Bearer $DOCKERHUB_TOKEN" \
  90. "https://hub.docker.com/v2/repositories/$DOCKERHUB_IMAGE/tags/$RELEASE_NAME/")
  91. if [[ "$status" == "204" ]]; then
  92. log "Deleted Docker Hub tag."
  93. else
  94. log "Docker Hub delete returned HTTP $status (tag may not exist or token invalid)." >&2
  95. fi
  96. fi
  97. else
  98. log "Skipped Docker Hub."
  99. fi
  100. log "Done."