Skip to content

Commit 2882dc9

Browse files
committed
add GH job and script to auto approve dependabot PRs.
Signed-off-by: Simon Davies <[email protected]>
1 parent 8feb67b commit 2882dc9

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

.github/dependabot.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ updates:
44
directory: "/"
55
schedule:
66
interval: "daily"
7+
time: "03:00"
78
labels:
89
- "kind/dependencies"
910
- package-ecosystem: "cargo"
1011
directory: "/"
1112
schedule:
1213
interval: "daily"
14+
time: "03:00"
1315
labels:
1416
- "kind/dependencies"
1517
ignore:
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Auto Merge Dependabot PRs
2+
3+
on:
4+
schedule:
5+
# Run daily at 04:00 UTC since dependabot runs at 03:00 UTC
6+
- cron: '0 4 * * *'
7+
workflow_dispatch: # Allow manual trigger
8+
9+
permissions:
10+
contents: write
11+
pull-requests: write
12+
13+
jobs:
14+
auto-merge-dependabot:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Setup GitHub CLI
21+
run: |
22+
# GitHub CLI is pre-installed on GitHub-hosted runners
23+
gh --version
24+
25+
- name: Make script executable
26+
run: chmod +x ./dev/auto-approve-dependabot.sh
27+
28+
- name: Run auto approve script
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
run: ./dev/auto-approve-dependabot.sh ${{ github.repository }}

dev/auto-approve-dependabot.sh

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/bin/bash
2+
set -e
3+
set -o pipefail
4+
5+
# This script checks for open PRs from dependabot that have all checks passing and have not been
6+
# modified by another user, and approves+merges them automatically.
7+
# To be run as a GitHub action.
8+
9+
# Check if repository argument is provided
10+
if [ -z "$1" ]; then
11+
echo "Error: Repository name not provided."
12+
echo "Usage: $0 <owner/repo>"
13+
echo "Example: $0 hyperlight-dev/hyperlight"
14+
exit 1
15+
fi
16+
17+
REPO="$1"
18+
echo "Checking for open Dependabot PRs to approve and merge in $REPO..."
19+
20+
# Get all open PRs from dependabot
21+
dependabot_prs=$(gh pr list -R "$REPO" --author "dependabot[bot]" --state open --json number,title,statusCheckRollup,reviews,url)
22+
23+
# Exit early if no PRs found
24+
if [ -z "$dependabot_prs" ] || [ "$dependabot_prs" = "[]" ]; then
25+
echo "No open Dependabot PRs found in $REPO"
26+
exit 0
27+
fi
28+
29+
# Count how many PRs we found
30+
pr_count=$(echo "$dependabot_prs" | jq 'length')
31+
echo "Found $pr_count open Dependabot PRs in $REPO"
32+
33+
# Process each PR
34+
echo "$dependabot_prs" | jq -c '.[]' | while read -r pr; do
35+
pr_number=$(echo "$pr" | jq -r '.number')
36+
pr_title=$(echo "$pr" | jq -r '.title')
37+
pr_url=$(echo "$pr" | jq -r '.url')
38+
39+
echo "Processing PR #$pr_number: $pr_title"
40+
41+
# Check if PR only modifies allowed files
42+
pr_files=$(gh pr view "$pr_number" -R "$REPO" --json files)
43+
invalid_files=$(echo "$pr_files" | jq -r '.files[].path' | grep -v -E '(Cargo\.toml|Cargo\.lock|\.github/workflows/.+)' || true)
44+
45+
if [ -n "$invalid_files" ]; then
46+
echo " ❌ PR #$pr_number modifies files that are not allowed for auto-merge:"
47+
echo "$invalid_files" | sed 's/^/ - /'
48+
echo " ℹ️ Only changes to Cargo.toml, Cargo.lock, or .github/workflows/ files are allowed"
49+
continue
50+
fi
51+
52+
echo " ✅ PR #$pr_number only modifies allowed files (Cargo.toml, Cargo.lock, or .github/workflows/)"
53+
54+
# First, get detailed PR information including all checks
55+
pr_details=$(gh pr view "$pr_number" -R "$REPO" --json statusCheckRollup,state)
56+
57+
# Check if all status checks have passed (regardless of required or not)
58+
all_checks_pass=true
59+
failed_checks=""
60+
61+
# Check all statusCheckRollup entries with conclusion different from SUCCESS
62+
failed_checks=$(echo "$pr_details" | jq -r '.statusCheckRollup[] | select(.conclusion != null and .conclusion != "SUCCESS" and .conclusion != "NEUTRAL" and .conclusion != "SKIPPED") | .name')
63+
64+
if [ -n "$failed_checks" ]; then
65+
echo " ❌ PR #$pr_number has failed checks:"
66+
echo "$failed_checks" | sed 's/^/ - /'
67+
all_checks_pass=false
68+
continue
69+
fi
70+
71+
# Check for pending status checks
72+
pending_checks=$(echo "$pr_details" | jq -r '.statusCheckRollup[] | select(.status == "IN_PROGRESS" or .status == "QUEUED" or .status == "PENDING") | .name')
73+
74+
if [ -n "$pending_checks" ]; then
75+
echo " ⏳ PR #$pr_number has pending checks:"
76+
echo "$pending_checks" | sed 's/^/ - /'
77+
all_checks_pass=false
78+
continue
79+
fi
80+
81+
echo " ✅ All status checks passed for PR #$pr_number"
82+
83+
# Check if PR has been modified by someone other than dependabot
84+
pr_commits=$(gh pr view "$pr_number" -R "$REPO" --json commits)
85+
non_dependabot_authors=$(echo "$pr_commits" | jq -r '.commits[].authors[].login' | grep -v -e "dependabot\[bot\]" -e "^$" || true)
86+
87+
if [ -n "$non_dependabot_authors" ]; then
88+
echo " ❌ PR #$pr_number has been modified by users other than dependabot: $non_dependabot_authors"
89+
continue
90+
fi
91+
92+
# Check if PR needs approval (i.e., hasn't been approved already)
93+
already_approved=$(echo "$pr" | jq -r '.reviews[] | select(.state == "APPROVED") | .state' | grep -c "APPROVED" || true)
94+
95+
if [ "$already_approved" -eq 0 ] && [ "$all_checks_pass" = true ]; then
96+
echo " ✅ Approving PR #$pr_number"
97+
gh pr review "$pr_number" -R "$REPO" --approve -b "Automatically approved by dependabot auto-approve workflow"
98+
else
99+
echo " ℹ️ PR #$pr_number is already approved or has failed checks"
100+
fi
101+
102+
# Check if we can merge the PR
103+
can_merge=$(gh pr view "$pr_number" -R "$REPO" --json mergeable -q '.mergeable')
104+
105+
if [ "$can_merge" = "MERGEABLE" ] && [ "$all_checks_pass" = true ]; then
106+
echo " ✅ Adding merge comment to PR #$pr_number"
107+
gh pr comment "$pr_number" -R "$REPO" -b "@dependabot merge"
108+
echo " ✅ Merge command issued for PR #$pr_number"
109+
else
110+
echo " ❌ PR #$pr_number is not mergeable at this time (status: $can_merge)"
111+
fi
112+
done
113+
114+
echo "Finished processing Dependabot PRs for $REPO"

0 commit comments

Comments
 (0)