1
+ name : Scheduled Dependabot PRs Auto-Merge
2
+
3
+ on :
4
+ schedule :
5
+ - cron : ' 0 0 * * *' # Runs once a day at midnight UTC
6
+ workflow_dispatch :
7
+
8
+ permissions :
9
+ contents : write
10
+ pull-requests : write
11
+
12
+ jobs :
13
+ merge-dependabot :
14
+ runs-on : ubuntu-latest
15
+ steps :
16
+ - name : Checkout repository
17
+ uses : actions/checkout@v4
18
+
19
+ - name : Install GitHub CLI
20
+ run : |
21
+ sudo apt update
22
+ sudo apt install -y gh
23
+
24
+ - name : Fetch & Filter Dependabot PRs
25
+ env :
26
+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
27
+ run : |
28
+ echo "🔍 Fetching all Dependabot PRs targeting 'dependabotchanges'..."
29
+ > matched_prs.txt
30
+ pr_batch=$(gh pr list --state open --json number,title,author,baseRefName,url \
31
+ --jq '.[] | "\(.number)|\(.title)|\(.author.login)|\(.baseRefName)|\(.url)"')
32
+ while IFS='|' read -r number title author base url; do
33
+ author=$(echo "$author" | xargs)
34
+ base=$(echo "$base" | xargs)
35
+ if [[ "$author" == "app/dependabot" && "$base" == "dependabotchanges" ]]; then
36
+ echo "$url" >> matched_prs.txt
37
+ echo "✅ Matched PR #$number - $title"
38
+ else
39
+ echo "❌ Skipped PR #$number - $title (Author: $author, Base: $base)"
40
+ fi
41
+ done <<< "$pr_batch"
42
+ echo "👉 Matched PRs:"
43
+ cat matched_prs.txt || echo "None"
44
+
45
+ - name : Rebase PR if Conflicts Exist
46
+ if : success()
47
+ env :
48
+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
49
+ run : |
50
+ if [[ ! -s matched_prs.txt ]]; then
51
+ echo "⚠️ No matching PRs to process."
52
+ exit 0
53
+ fi
54
+ while IFS= read -r pr_url; do
55
+ pr_number=$(basename "$pr_url")
56
+ echo "🔁 Rebasing PR #$pr_number if conflicts exist"
57
+ mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable')
58
+ 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."
61
+ fi
62
+ done < matched_prs.txt
63
+
64
+ - name : Auto-Merge if Mergeable
65
+ if : success()
66
+ env :
67
+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
68
+ run : |
69
+ if [[ ! -s matched_prs.txt ]]; then
70
+ echo "⚠️ No matching PRs to process."
71
+ exit 0
72
+ fi
73
+ while IFS= read -r pr_url; do
74
+ echo "🔍 Checking mergeability for $pr_url"
75
+ pr_number=$(basename "$pr_url")
76
+ attempt=0
77
+ max_attempts=8
78
+ mergeable=""
79
+ sleep 5 # Initial delay to allow GitHub to compute mergeability
80
+ while [[ $attempt -lt $max_attempts ]]; do
81
+ mergeable=$(gh pr view "$pr_number" --json mergeable --jq '.mergeable' 2>/dev/null || echo "UNKNOWN")
82
+ echo "🔁 Attempt $((attempt+1))/$max_attempts: mergeable=$mergeable"
83
+ 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!"
94
+ fi
95
+ break
96
+ elif [[ "$mergeable" == "CONFLICTING" ]]; then
97
+ echo "❌ Cannot merge due to conflicts. Skipping."
98
+ break
99
+ else
100
+ echo "🕒 Waiting for GitHub to determine mergeable status..."
101
+ sleep 15
102
+ fi
103
+ ((attempt++))
104
+ done
105
+ if [[ "$mergeable" != "MERGEABLE" && "$mergeable" != "CONFLICTING" ]]; then
106
+ echo "❌ Mergeability undetermined after $max_attempts attempts. Skipping PR #$pr_number"
107
+ fi
108
+ done < matched_prs.txt || echo "⚠️ Completed loop with some errors, but continuing gracefully."
0 commit comments