11name : Auto Delete Merged Branches
22
33on :
4+ pull_request :
5+ types : [closed] # Triggers when a PR is closed
46 schedule :
5- - cron : ' 0 0 * * * ' # Runs at midnight UTC every day
7+ - cron : ' 0 0 * * 0 ' # Runs weekly on Sundays at midnight UTC
68 workflow_dispatch : # Allows manual triggering
79
810permissions :
911 contents : write # Required to delete branches
12+ pull-requests : read # Required to check PR status
1013
1114jobs :
1215 delete-merged-branches :
@@ -15,12 +18,59 @@ jobs:
1518 steps :
1619 - name : Checkout Repository
1720 uses : actions/checkout@v3
18-
19- - name : Delete Merged Branches
20- uses : SvanBoxel/delete-merged-branch@2b5b058e3db41a3328fd9a6a58fd4c2545a14353
2121 with :
22- # A list of branches that should not be deleted.
23- # Add any new protected branches to this list.
24- exclude : main, saas, cli-tool
25- # Set to true to also delete branches from closed (but not merged) PRs
26- delete_closed_pr : false
22+ fetch-depth : 0 # Fetch all branches and history
23+
24+ - name : Delete Merged Branches with GitHub CLI
25+ env :
26+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
27+ run : |
28+ # Protected branches that should never be deleted
29+ PROTECTED_BRANCHES=("main" "saas" "cli-tool")
30+
31+ echo "🔍 Finding merged branches..."
32+
33+ # Get all remote branches
34+ git fetch --all --prune
35+
36+ # Get the default branch
37+ DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
38+ echo "Default branch: $DEFAULT_BRANCH"
39+
40+ DELETED_COUNT=0
41+ SKIPPED_COUNT=0
42+
43+ # Loop through all remote branches
44+ for branch in $(git branch -r | grep -v '\->' | sed 's/origin\///'); do
45+ # Skip protected branches
46+ SKIP=false
47+ for protected in "${PROTECTED_BRANCHES[@]}"; do
48+ if [ "$branch" = "$protected" ]; then
49+ SKIP=true
50+ break
51+ fi
52+ done
53+
54+ if [ "$SKIP" = true ]; then
55+ echo "⏭️ Skipping protected branch: $branch"
56+ ((SKIPPED_COUNT++))
57+ continue
58+ fi
59+
60+ # Check if branch is merged into default branch
61+ MERGE_BASE=$(git merge-base $DEFAULT_BRANCH origin/$branch 2>/dev/null || echo "")
62+ BRANCH_COMMIT=$(git rev-parse origin/$branch 2>/dev/null || echo "")
63+
64+ if [ -n "$MERGE_BASE" ] && [ -n "$BRANCH_COMMIT" ] && [ "$MERGE_BASE" = "$BRANCH_COMMIT" ]; then
65+ echo "🗑️ Deleting merged branch: $branch"
66+ git push origin --delete "$branch" 2>&1 || echo "⚠️ Failed to delete $branch"
67+ ((DELETED_COUNT++))
68+ else
69+ echo "⏭️ Skipping unmerged branch: $branch"
70+ ((SKIPPED_COUNT++))
71+ fi
72+ done
73+
74+ echo "✅ Cleanup complete!"
75+ echo " - Deleted: $DELETED_COUNT branches"
76+ echo " - Skipped: $SKIPPED_COUNT branches"
0 commit comments