Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 124 additions & 10 deletions .github/workflows/cleanup-pre-releases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ name: Cleanup Obsolete Releases (PRs and RCs)

on:
workflow_dispatch:
inputs:
dry_run:
description: "Dry run mode - show what would be deleted without actually deleting"
required: false
default: "false"
type: boolean
schedule:
- cron: "0 2 * * *" # Optional: runs daily at 2am UTC
pull_request_target:
Expand All @@ -24,6 +30,16 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Set dry run mode
DRY_RUN="${{ inputs.dry_run || 'false' }}"

if [[ "$DRY_RUN" == "true" ]]; then
echo "🔍 DRY RUN MODE: Will show what would be deleted without actually deleting"
else
echo "🗑️ DELETION MODE: Will actually delete obsolete tags and releases"
fi
echo ""

# This script cleans up pre-release tags and releases in two ways:
#
# 1. PR Prereleases (e.g., v1.2.3-pr123):
Expand All @@ -34,29 +50,62 @@ jobs:
# - These are deleted if the corresponding final release (e.g., v1.2.3) exists and is not a prerelease.
#
# Final release tags (e.g., v1.2.3) are NEVER deleted by this script.
echo "Fetching all prereleases..."
echo "Fetching all prereleases and orphaned pre-release tags..."

# Get pre-release GitHub releases
releases=$(gh release list --limit 1000 --json tagName,isPrerelease --jq '.[] | select(.isPrerelease) | .tagName')

for tag in $releases; do
# Get all git tags that look like pre-releases but may not have GitHub releases
git fetch --tags
orphaned_tags=$(git tag -l | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-(pr[0-9]+|rc[0-9]+|alpha[0-9]*|beta[0-9]*|dev[0-9]*)' || true)

# Combine both lists and remove duplicates
all_prerelease_tags=$(echo -e "$releases\n$orphaned_tags" | sort | uniq | grep -v '^$' || true)

# Initialize counters and lists
total_tags=0
would_delete=0
would_keep=0
tags_to_delete=""
tags_to_keep=""

for tag in $all_prerelease_tags; do
total_tags=$((total_tags + 1))
if [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-pr([0-9]+)$ ]]; then
pr_number="${BASH_REMATCH[1]}"
echo "Checking PR #$pr_number for tag $tag"

pr_info=$(gh pr view "$pr_number" --json state,isDraft 2>/dev/null || echo "NOT_FOUND")
if [[ "$pr_info" == "NOT_FOUND" ]]; then
echo "PR #$pr_number not found. Deleting prerelease tag $tag"
gh release delete "$tag" --yes --cleanup-tag
would_delete=$((would_delete + 1))
tags_to_delete="$tags_to_delete$tag (PR #$pr_number not found)\n"
if [[ "$DRY_RUN" == "true" ]]; then
echo "🔍 [DRY RUN] Would delete: PR #$pr_number not found. Tag $tag would be deleted"
else
echo "🗑️ PR #$pr_number not found. Deleting prerelease tag $tag"
# Try to delete as release first, then as tag if no release exists
gh release delete "$tag" --yes --cleanup-tag 2>/dev/null || git push --delete origin "$tag" 2>/dev/null || echo "Failed to delete $tag"
fi
continue
fi

pr_state=$(echo "$pr_info" | jq -r '.state')
pr_draft=$(echo "$pr_info" | jq -r '.isDraft')

if [[ "$pr_state" != "OPEN" || "$pr_draft" == "true" ]]; then
echo "PR #$pr_number is $pr_state${pr_draft:+ (draft)}. Deleting prerelease tag $tag"
gh release delete "$tag" --yes --cleanup-tag
would_delete=$((would_delete + 1))
tags_to_delete="$tags_to_delete$tag (PR #$pr_number is $pr_state${pr_draft:+ (draft)})\n"
if [[ "$DRY_RUN" == "true" ]]; then
echo "🔍 [DRY RUN] Would delete: PR #$pr_number is $pr_state${pr_draft:+ (draft)}. Tag $tag would be deleted"
else
echo "🗑️ PR #$pr_number is $pr_state${pr_draft:+ (draft)}. Deleting prerelease tag $tag"
# Try to delete as release first, then as tag if no release exists
gh release delete "$tag" --yes --cleanup-tag 2>/dev/null || git push --delete origin "$tag" 2>/dev/null || echo "Failed to delete $tag"
fi
else
echo "PR #$pr_number is open and not draft. Keeping tag $tag"
would_keep=$((would_keep + 1))
tags_to_keep="$tags_to_keep$tag (PR #$pr_number is open)\n"
echo "✅ PR #$pr_number is open and not draft. Keeping tag $tag"
fi
elif [[ "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-.+ ]]; then
# Exclude -pr* tags
Expand All @@ -66,12 +115,77 @@ jobs:
base_tag="${tag%%-*}"
final_release=$(gh release view "$base_tag" --json isPrerelease -q '.isPrerelease' 2>/dev/null || echo "NOT_FOUND")
if [[ "$final_release" == "false" ]]; then
echo "Final release $base_tag exists. Deleting obsolete prerelease $tag"
gh release delete "$tag" --yes --cleanup-tag
would_delete=$((would_delete + 1))
tags_to_delete="$tags_to_delete$tag (final release $base_tag exists)\n"
if [[ "$DRY_RUN" == "true" ]]; then
echo "🔍 [DRY RUN] Would delete: Final release $base_tag exists. Tag $tag would be deleted"
else
echo "🗑️ Final release $base_tag exists. Deleting obsolete prerelease $tag"
# Try to delete as release first, then as tag if no release exists
gh release delete "$tag" --yes --cleanup-tag 2>/dev/null || git push --delete origin "$tag" 2>/dev/null || echo "Failed to delete $tag"
fi
else
echo "Final release $base_tag not found or is a prerelease. Keeping $tag"
would_keep=$((would_keep + 1))
tags_to_keep="$tags_to_keep$tag (final release $base_tag not found)\n"
echo "✅ Final release $base_tag not found or is a prerelease. Keeping $tag"
fi
else
echo "Skipping non-pre-release tag $tag"
fi
done

echo ""
echo "📊 SUMMARY:"
echo "Total pre-release tags found: $total_tags"

if [[ "$DRY_RUN" == "true" ]]; then
echo "Tags that would be deleted: $would_delete"
echo "Tags that would be kept: $would_keep"
echo ""

if [[ $would_delete -gt 0 ]]; then
echo "🗑️ Tags that WOULD BE DELETED:"
echo -e "$tags_to_delete" | while IFS= read -r line; do
if [[ -n "$line" ]]; then
tag_name=$(echo "$line" | cut -d' ' -f1)
reason=$(echo "$line" | cut -d'(' -f2- | sed 's/)$//')
echo " • $tag_name - $reason"
echo " 🔗 https://github.com/doodlum/skyrim-community-shaders/releases/tag/$tag_name"
fi
done
echo ""
fi

if [[ $would_keep -gt 0 ]]; then
echo "✅ Tags that would be KEPT:"
echo -e "$tags_to_keep" | while IFS= read -r line; do
if [[ -n "$line" ]]; then
tag_name=$(echo "$line" | cut -d' ' -f1)
reason=$(echo "$line" | cut -d'(' -f2- | sed 's/)$//')
echo " • $tag_name - $reason"
fi
done
echo ""
fi

echo "🔍 This was a DRY RUN - no tags were actually deleted."
echo "To perform actual deletion, run this workflow with dry_run=false"
else
echo "Tags deleted: $would_delete"
echo "Tags kept: $would_keep"
echo ""

if [[ $would_delete -gt 0 ]]; then
echo "🗑️ Tags that were DELETED:"
echo -e "$tags_to_delete" | while IFS= read -r line; do
if [[ -n "$line" ]]; then
tag_name=$(echo "$line" | cut -d' ' -f1)
reason=$(echo "$line" | cut -d'(' -f2- | sed 's/)$//')
echo " • $tag_name - $reason"
fi
done
echo ""
fi

echo "🗑️ Cleanup completed successfully!"
fi