1
+ # ------------------------------------------------------------------------------
2
+ # Scheduled Dependabot PRs Auto-Merge Workflow
3
+ #
4
+ # Purpose:
5
+ # - Automatically detect, rebase (if needed), and merge Dependabot PRs targeting
6
+ # the `dependabotchanges` branch, supporting different merge strategies.
7
+ #
8
+ # Features:
9
+ # ✅ Filters PRs authored by Dependabot and targets the specific base branch
10
+ # ✅ Rebases PRs with conflicts and auto-resolves using "prefer-theirs" strategy
11
+ # ✅ Attempts all three merge strategies: merge, squash, rebase (first success wins)
12
+ # ✅ Handles errors gracefully, logs clearly
13
+ #
14
+ # Triggers:
15
+ # - Scheduled daily run (midnight UTC)
16
+ # - Manual trigger (via GitHub UI)
17
+ #
18
+ # Required Permissions:
19
+ # - contents: write
20
+ # - pull-requests: write
21
+ # ------------------------------------------------------------------------------
22
+
1
23
name : Scheduled Dependabot PRs Auto-Merge
2
24
3
25
on :
20
42
run : |
21
43
sudo apt update
22
44
sudo apt install -y gh
23
-
24
45
- name : Fetch & Filter Dependabot PRs
25
46
env :
26
47
GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
41
62
done <<< "$pr_batch"
42
63
echo "👉 Matched PRs:"
43
64
cat matched_prs.txt || echo "None"
44
-
45
65
- name : Rebase PR if Conflicts Exist
46
66
if : success()
47
67
env :
@@ -53,15 +73,31 @@ jobs:
53
73
fi
54
74
while IFS= read -r pr_url; do
55
75
pr_number=$(basename "$pr_url")
56
- echo "🔁 Rebasing PR #$pr_number if conflicts exist "
76
+ echo "🔁 Checking PR #$pr_number for conflicts... "
57
77
mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable')
58
78
if [[ "$mergeable" == "CONFLICTING" ]]; then
59
- echo "❌ Merge conflicts detected. Rebasing PR #$pr_number"
60
- gh pr update-branch "$pr_url" || echo "❗ Rebase (update-branch) failed."
79
+ echo "⚠️ Merge conflicts detected. Performing manual rebase for PR #$pr_number..."
80
+ head_branch=$(gh pr view "$pr_number" --json headRefName --jq '.headRefName')
81
+ base_branch=$(gh pr view "$pr_number" --json baseRefName --jq '.baseRefName')
82
+ git fetch origin "$base_branch":"$base_branch"
83
+ git fetch origin "$head_branch":"$head_branch"
84
+ git checkout "$head_branch"
85
+ git config user.name "github-actions"
86
+ git config user.email "[email protected] "
87
+ # Attempt rebase with 'theirs' strategy
88
+ if git rebase --strategy=recursive -X theirs "$base_branch"; then
89
+ echo "✅ Rebase successful. Pushing..."
90
+ git push origin "$head_branch" --force
91
+ else
92
+ echo "❌ Rebase failed. Aborting..."
93
+ git rebase --abort || true
94
+ fi
95
+ else
96
+ echo "✅ PR #$pr_number is mergeable. Skipping rebase."
61
97
fi
62
98
done < matched_prs.txt
63
-
64
- - name : Auto-Merge if Mergeable
99
+
100
+ - name : Auto-Merge PRs using available strategy
65
101
if : success()
66
102
env :
67
103
GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
@@ -71,30 +107,38 @@ jobs:
71
107
exit 0
72
108
fi
73
109
while IFS= read -r pr_url; do
74
- echo "🔍 Checking mergeability for $pr_url"
75
110
pr_number=$(basename "$pr_url")
111
+ echo "🔍 Checking mergeability for PR #$pr_number"
76
112
attempt=0
77
113
max_attempts=8
78
114
mergeable=""
79
- sleep 5 # Initial delay to allow GitHub to compute mergeability
115
+ sleep 5 # Let GitHub calculate mergeable status
80
116
while [[ $attempt -lt $max_attempts ]]; do
81
117
mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable' 2>/dev/null || echo "UNKNOWN")
82
118
echo "🔁 Attempt $((attempt+1))/$max_attempts: mergeable=$mergeable"
83
119
if [[ "$mergeable" == "MERGEABLE" ]]; then
84
- echo "🚀 Enabling auto-merge..."
85
- set -x
86
- merge_output=$(gh pr merge --auto --merge "$pr_url" 2>&1)
87
- merge_status=$?
88
- set +x
89
- echo "$merge_output"
90
- if [[ $merge_status -ne 0 ]]; then
91
- echo "❗ Auto-merge failed. Output: $merge_output"
92
- else
93
- echo "✅ Auto-merge succeeded!"
120
+ success=0
121
+ for strategy in rebase squash merge; do
122
+ echo "🚀 Trying to auto-merge PR #$pr_number using '$strategy' strategy..."
123
+ set -x
124
+ merge_output=$(gh pr merge --auto --"$strategy" "$pr_url" 2>&1)
125
+ merge_status=$?
126
+ set +x
127
+ echo "$merge_output"
128
+ if [[ $merge_status -eq 0 ]]; then
129
+ echo "✅ Auto-merge succeeded using '$strategy'."
130
+ success=1
131
+ break
132
+ else
133
+ echo "❌ Auto-merge failed using '$strategy'. Trying next strategy..."
134
+ fi
135
+ done
136
+ if [[ $success -eq 0 ]]; then
137
+ echo "❌ All merge strategies failed for PR #$pr_number"
94
138
fi
95
139
break
96
140
elif [[ "$mergeable" == "CONFLICTING" ]]; then
97
- echo "❌ Cannot merge due to conflicts. Skipping. "
141
+ echo "❌ Cannot merge due to conflicts. Skipping PR #$pr_number "
98
142
break
99
143
else
100
144
echo "🕒 Waiting for GitHub to determine mergeable status..."
0 commit comments