Skip to content

Commit 1017cf0

Browse files
committed
add GH job and script to auto approve dependabot PRs.
Signed-off-by: Simon Davies <[email protected]>
1 parent 4918fcd commit 1017cf0

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

.github/dependabot.yml

+2
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:
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

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
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,reviews)
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+
38+
echo "Processing PR #$pr_number: $pr_title"
39+
40+
# Check if PR only modifies allowed files
41+
pr_files=$(gh pr view "$pr_number" -R "$REPO" --json files)
42+
invalid_files=$(echo "$pr_files" | jq -r '.files[].path' | grep -v -E '(Cargo\.toml|Cargo\.lock|\.github/workflows/.+)' || true)
43+
44+
if [ -n "$invalid_files" ]; then
45+
echo " ❌ PR #$pr_number modifies files that are not allowed for auto-merge:"
46+
echo ${invalid_files/#/ - }
47+
echo " ℹ️ Only changes to Cargo.toml, Cargo.lock, or .github/workflows/ files are allowed"
48+
continue
49+
fi
50+
51+
echo " ✅ PR #$pr_number only modifies allowed files (Cargo.toml, Cargo.lock, or .github/workflows/)"
52+
53+
# First, get detailed PR information including all checks
54+
pr_details=$(gh pr view "$pr_number" -R "$REPO" --json statusCheckRollup,state)
55+
56+
# Check if all status checks have passed (regardless of required or not)
57+
all_checks_pass=true
58+
has_pending_checks=false
59+
failed_checks=""
60+
61+
# First identify checks that are still in progress
62+
pending_checks=$(echo "$pr_details" | jq -r '.statusCheckRollup[] | select(.status == "IN_PROGRESS" or .status == "QUEUED" or .status == "PENDING") | .name')
63+
64+
if [ -n "$pending_checks" ]; then
65+
echo " ⏳ PR #$pr_number has pending checks:"
66+
echo "$pending_checks" | sed 's/^/ - /'
67+
echo " ℹ️ We will still approve the PR so it can merge automatically once all checks pass"
68+
has_pending_checks=true
69+
fi
70+
71+
# Check for failed checks - only include checks that have a conclusion and are not still running
72+
# Explicitly exclude checks with status IN_PROGRESS, QUEUED, or PENDING
73+
failed_checks=$(echo "$pr_details" | jq -r '.statusCheckRollup[] |
74+
select(.conclusion != null and
75+
.conclusion != "SUCCESS" and
76+
.conclusion != "NEUTRAL" and
77+
.conclusion != "SKIPPED" and
78+
.status != "IN_PROGRESS" and
79+
.status != "QUEUED" and
80+
.status != "PENDING") | .name')
81+
82+
if [ -n "$failed_checks" ]; then
83+
echo " ❌ PR #$pr_number has failed checks:"
84+
echo "$failed_checks" | sed 's/^/ - /'
85+
all_checks_pass=false
86+
continue
87+
fi
88+
89+
# If we've reached here, either all checks have passed or some are pending
90+
if [ "$has_pending_checks" = false ]; then
91+
echo " ✅ All status checks passed for PR #$pr_number"
92+
fi
93+
94+
# Check if PR has been modified by someone other than dependabot
95+
pr_commits=$(gh pr view "$pr_number" -R "$REPO" --json commits)
96+
non_dependabot_authors=$(echo "$pr_commits" | jq -r '.commits[].authors[].login' | grep -v -e "dependabot\[bot\]" -e "^$" || true)
97+
98+
if [ -n "$non_dependabot_authors" ]; then
99+
echo " ❌ PR #$pr_number has been modified by users other than dependabot: $non_dependabot_authors"
100+
continue
101+
fi
102+
103+
# Check if PR needs approval (i.e., hasn't been approved already)
104+
already_approved=$(echo "$pr" | jq -r '.reviews[] | select(.state == "APPROVED") | .state' | grep -c "APPROVED" || true)
105+
106+
if [ "$already_approved" -eq 0 ]; then
107+
echo " ✅ Approving PR #$pr_number"
108+
gh pr review "$pr_number" -R "$REPO" --approve -b "Automatically approved by dependabot auto-approve workflow"
109+
else
110+
echo " ℹ️ PR #$pr_number is already approved"
111+
fi
112+
113+
if [ "$has_pending_checks" = true ] || [ "$all_checks_pass" = true ]; then
114+
echo " ✅ Adding merge comment to PR #$pr_number"
115+
gh pr comment "$pr_number" -R "$REPO" -b "@dependabot merge"
116+
echo " ✅ Merge command issued for PR #$pr_number"
117+
fi
118+
119+
done
120+
121+
echo "Finished processing Dependabot PRs for $REPO"

0 commit comments

Comments
 (0)