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