Skip to content

Cleanup Merged Branches #67

Cleanup Merged Branches

Cleanup Merged Branches #67

name: Cleanup Merged Branches
on:
pull_request:
types: [closed]
schedule:
# Run weekly on Sunday at 00:00 UTC to clean up stale branches
- cron: '0 0 * * 0'
workflow_dispatch:
inputs:
dry_run:
description: 'Dry run (show branches without deleting)'
required: false
type: boolean
default: true
permissions:
contents: write
pull-requests: read
jobs:
cleanup-pr-branch:
name: Delete merged PR branch
# Only run for closed PRs that were merged
if: |
github.event_name == 'pull_request' &&
github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Delete branch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BRANCH_NAME: ${{ github.event.pull_request.head.ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
run: |
# Only delete auto-update branches
if [[ ! "$BRANCH_NAME" =~ ^auto-update/ ]]; then
echo "Branch '$BRANCH_NAME' is not an auto-update branch, skipping"
exit 0
fi
echo "PR #$PR_NUMBER was merged"
echo "Deleting branch: $BRANCH_NAME"
gh api --method DELETE \
"repos/$REPO/git/refs/heads/$BRANCH_NAME" \
&& echo "✓ Branch deleted successfully" \
|| echo "⚠ Branch may have been already deleted"
cleanup-stale-branches:
name: Cleanup all stale merged branches
# Run on manual dispatch or scheduled runs
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- name: Find and delete stale auto-update branches
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# For scheduled runs, default to dry_run=false (actually delete)
DRY_RUN: ${{ github.event_name == 'schedule' && 'false' || inputs.dry_run }}
REPO: ${{ github.repository }}
run: |
echo "Searching for merged auto-update/* branches..."
# Get all auto-update branches
BRANCHES=$(gh api "repos/$REPO/branches" \
--paginate \
--jq '.[] | select(.name | startswith("auto-update/")) | .name')
if [ -z "$BRANCHES" ]; then
echo "No auto-update branches found"
exit 0
fi
DELETED=0
SKIPPED=0
while IFS= read -r BRANCH; do
echo ""
echo "Checking branch: $BRANCH"
# Check via PR API (handles squash, rebase, and merge-commit strategies)
MERGED_PR=$(gh pr list --repo "$REPO" --head "$BRANCH" --state merged --json number --jq '.[0].number')
if [ -n "$MERGED_PR" ]; then
echo " ✓ PR #$MERGED_PR was merged"
if [ "$DRY_RUN" = "true" ]; then
echo " [DRY RUN] Would delete: $BRANCH"
DELETED=$((DELETED + 1))
else
if gh api --method DELETE "repos/$REPO/git/refs/heads/$BRANCH"; then
echo " ✓ Deleted: $BRANCH"
DELETED=$((DELETED + 1))
else
echo " ✗ Failed to delete: $BRANCH"
SKIPPED=$((SKIPPED + 1))
fi
fi
else
echo " ⊘ No merged PR found for this branch, keeping it"
SKIPPED=$((SKIPPED + 1))
fi
sleep 0.5 # Rate limiting
done <<< "$BRANCHES"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ "$DRY_RUN" = "true" ]; then
echo "DRY RUN SUMMARY:"
echo " Would delete: $DELETED branches"
echo " Would keep: $SKIPPED branches"
echo ""
echo "Run with dry_run=false to actually delete branches"
else
echo "CLEANUP SUMMARY:"
echo " Deleted: $DELETED branches"
echo " Skipped: $SKIPPED branches"
fi