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+
123name : Scheduled Dependabot PRs Auto-Merge
224
325on :
2042 run : |
2143 sudo apt update
2244 sudo apt install -y gh
23-
2445 - name : Fetch & Filter Dependabot PRs
2546 env :
2647 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
4162 done <<< "$pr_batch"
4263 echo "👉 Matched PRs:"
4364 cat matched_prs.txt || echo "None"
44-
4565 - name : Rebase PR if Conflicts Exist
4666 if : success()
4767 env :
@@ -53,15 +73,31 @@ jobs:
5373 fi
5474 while IFS= read -r pr_url; do
5575 pr_number=$(basename "$pr_url")
56- echo "🔁 Rebasing PR #$pr_number if conflicts exist "
76+ echo "🔁 Checking PR #$pr_number for conflicts... "
5777 mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable')
5878 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."
6197 fi
6298 done < matched_prs.txt
63-
64- - name : Auto-Merge if Mergeable
99+
100+ - name : Auto-Merge PRs using available strategy
65101 if : success()
66102 env :
67103 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
@@ -71,30 +107,38 @@ jobs:
71107 exit 0
72108 fi
73109 while IFS= read -r pr_url; do
74- echo "🔍 Checking mergeability for $pr_url"
75110 pr_number=$(basename "$pr_url")
111+ echo "🔍 Checking mergeability for PR #$pr_number"
76112 attempt=0
77113 max_attempts=8
78114 mergeable=""
79- sleep 5 # Initial delay to allow GitHub to compute mergeability
115+ sleep 5 # Let GitHub calculate mergeable status
80116 while [[ $attempt -lt $max_attempts ]]; do
81117 mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable' 2>/dev/null || echo "UNKNOWN")
82118 echo "🔁 Attempt $((attempt+1))/$max_attempts: mergeable=$mergeable"
83119 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"
94138 fi
95139 break
96140 elif [[ "$mergeable" == "CONFLICTING" ]]; then
97- echo "❌ Cannot merge due to conflicts. Skipping. "
141+ echo "❌ Cannot merge due to conflicts. Skipping PR #$pr_number "
98142 break
99143 else
100144 echo "🕒 Waiting for GitHub to determine mergeable status..."
0 commit comments