Skip to content

Commit e093ef2

Browse files
committed
feat(ci): cleanup backport branches
1 parent 1752433 commit e093ef2

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
name: Cleanup backport branches
2+
3+
permissions:
4+
contents: write
5+
6+
on:
7+
pull_request:
8+
types: [closed]
9+
schedule:
10+
- cron: '0 2 * * 0' # Weekly on Sunday at 2 AM UTC
11+
workflow_dispatch:
12+
inputs:
13+
dry_run:
14+
description: 'Dry run mode (true/false)'
15+
required: false
16+
default: 'true'
17+
type: choice
18+
options:
19+
- 'true'
20+
- 'false'
21+
22+
jobs:
23+
# Immediate cleanup when a backport PR is merged
24+
delete-on-merge:
25+
name: Delete merged backport branch
26+
if: |
27+
github.event_name == 'pull_request' &&
28+
github.event.pull_request.merged == true &&
29+
startsWith(github.head_ref, 'backport/')
30+
runs-on: ubuntu-latest
31+
steps:
32+
- name: Delete merged backport branch
33+
uses: jessfraz/branch-cleanup-action@master
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }}
36+
37+
# Weekly cleanup of any merged backport branches older than 7 days
38+
scheduled-cleanup:
39+
name: Cleanup old backport branches
40+
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
41+
runs-on: ubuntu-latest
42+
steps:
43+
- name: Checkout repository
44+
uses: actions/checkout@v5
45+
with:
46+
fetch-depth: 0
47+
token: ${{ secrets.GH_ACCESS_TOKEN }}
48+
49+
- name: Setup cleanup parameters
50+
id: params
51+
run: |
52+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
53+
echo "dry_run=${{ github.event.inputs.dry_run }}" >> $GITHUB_OUTPUT
54+
else
55+
# For scheduled runs, use dry_run=false (actually delete)
56+
echo "dry_run=false" >> $GITHUB_OUTPUT
57+
fi
58+
59+
- name: Cleanup old merged backport branches
60+
run: |
61+
DRY_RUN="${{ steps.params.outputs.dry_run }}"
62+
63+
echo "=== Backport Branch Cleanup ==="
64+
echo "Dry run mode: $DRY_RUN"
65+
echo "Searching for merged backport branches older than 7 days..."
66+
echo ""
67+
68+
# Fetch all branches
69+
git fetch origin
70+
71+
# Get main/master branch name
72+
MAIN_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
73+
echo "Main branch: $MAIN_BRANCH"
74+
echo ""
75+
76+
DELETED_COUNT=0
77+
SKIPPED_COUNT=0
78+
79+
# Find all backport branches merged into main
80+
for branch in $(git branch -r --merged "origin/$MAIN_BRANCH" | grep 'origin/backport/' | sed 's/origin\///'); do
81+
# Get the merge commit timestamp from main branch (when the branch was actually merged)
82+
# Find the merge commit in main that contains commits from this branch
83+
branch_head=$(git rev-parse "origin/$branch" 2>/dev/null || echo "")
84+
if [ -z "$branch_head" ]; then
85+
echo "⚠️ Skipping $branch (unable to get branch head)"
86+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
87+
continue
88+
fi
89+
90+
# Find merge commit in main that merged this branch
91+
merge_commit=$(git log "origin/$MAIN_BRANCH" --merges --first-parent --format="%H %ct" | \
92+
while read -r commit_hash commit_time; do
93+
if git merge-base --is-ancestor "$branch_head" "$commit_hash" 2>/dev/null; then
94+
echo "$commit_time"
95+
break
96+
fi
97+
done)
98+
99+
if [ -z "$merge_commit" ]; then
100+
echo "⚠️ Skipping $branch (unable to find merge commit)"
101+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
102+
continue
103+
fi
104+
105+
current_timestamp=$(date +%s)
106+
days_old=$(( ( current_timestamp - merge_commit ) / 86400 ))
107+
108+
if [ $days_old -gt 7 ]; then
109+
if [ "$DRY_RUN" = "true" ]; then
110+
echo "🔍 [DRY RUN] Would delete: $branch (${days_old} days old)"
111+
DELETED_COUNT=$((DELETED_COUNT + 1))
112+
else
113+
echo "🗑️ Deleting: $branch (${days_old} days old)"
114+
if git push origin --delete "$branch" 2>/dev/null; then
115+
echo " ✅ Successfully deleted"
116+
DELETED_COUNT=$((DELETED_COUNT + 1))
117+
else
118+
echo " ❌ Failed to delete"
119+
SKIPPED_COUNT=$((SKIPPED_COUNT + 1))
120+
fi
121+
fi
122+
fi
123+
done
124+
125+
echo ""
126+
echo "=== Summary ==="
127+
if [ "$DRY_RUN" = "true" ]; then
128+
echo "Branches that would be deleted: $DELETED_COUNT"
129+
else
130+
echo "Branches deleted: $DELETED_COUNT"
131+
fi
132+
echo "Branches skipped: $SKIPPED_COUNT"

0 commit comments

Comments
 (0)