1+ # Taken from lh
2+
3+ name : Auto Merge Dependabot PRs
4+
5+ on :
6+ pull_request :
7+ types :
8+ - opened
9+ - synchronize
10+
11+ permissions :
12+ pull-requests : write
13+ contents : write
14+
15+ jobs :
16+ auto-merge :
17+ runs-on : ubuntu-latest
18+ if : github.actor == 'dependabot[bot]'
19+
20+ steps :
21+ - name : Checkout the repository
22+ uses : actions/checkout@v3
23+
24+ - name : Set up GitHub CLI
25+ run : |
26+ # Install GitHub CLI (gh)
27+ sudo apt-get update
28+ sudo apt-get install gh
29+
30+ # Authenticate GitHub CLI using the provided token
31+ echo ${{ secrets.GITHUB_TOKEN }} | gh auth login --with-token
32+
33+ - name : Wait for CI workflow to pass (Ensure CI workflow succeeded)
34+ id : wait_for_ci
35+ run : |
36+ # Get the PR number from the GitHub event
37+ PR_NUMBER=${{ github.event.pull_request.number }}
38+ echo "Checking CI status for PR #$PR_NUMBER"
39+
40+ # Define the maximum wait time (in seconds) and the polling interval (in seconds)
41+ MAX_WAIT_TIME=1800 # 30 minutes
42+ POLL_INTERVAL=10 # Check every 10 seconds
43+
44+ # Initialize a timer
45+ elapsed_time=0
46+
47+ # Poll CI status until all checks are completed
48+ while true; do
49+ # Fetch the status check rollup for the PR
50+ CI_STATUS=$(gh pr view $PR_NUMBER --json statusCheckRollup)
51+
52+ # Log the fetched response
53+ echo "CI Status Response: $CI_STATUS"
54+
55+ # Parse the checks and check their status
56+ ALL_COMPLETED=true
57+ ALL_CHECKS_PASSED=true
58+
59+ for check in $(echo "$CI_STATUS" | jq -r '.statusCheckRollup[] | @base64'); do
60+ _jq() {
61+ echo "${check}" | base64 --decode | jq -r "${1}"
62+ }
63+
64+ status=$(_jq '.status')
65+ conclusion=$(_jq '.conclusion')
66+ check_name=$(_jq '.name')
67+
68+ # Log check details
69+ echo "Check: $check_name, Status: $status, Conclusion: $conclusion"
70+ if [[ "$check_name" == "auto-merge" ]]; then
71+ echo "Skipping 'auto-merge' workflow check to prevent self-referencing."
72+ continue
73+ fi
74+
75+ # If any check is still queued, set ALL_COMPLETED to false
76+ if [[ "$status" == "QUEUED" ]]; then
77+ ALL_COMPLETED=false
78+ fi
79+
80+ # If any check is still in progress, set ALL_COMPLETED to false
81+ if [[ "$status" == "IN_PROGRESS" ]]; then
82+ ALL_COMPLETED=false
83+ fi
84+
85+ # If any completed check has failed, set ALL_CHECKS_PASSED to false
86+ if [[ "$status" == "COMPLETED" && "$conclusion" != "SUCCESS" ]]; then
87+ ALL_CHECKS_PASSED=false
88+ fi
89+ done
90+
91+ # Break the loop if all checks are completed
92+ if [[ "$ALL_COMPLETED" == true ]]; then
93+ break
94+ fi
95+
96+ # Wait for the next polling interval
97+ echo "Waiting for checks to complete... ($elapsed_time/$MAX_WAIT_TIME seconds elapsed)"
98+ sleep $POLL_INTERVAL
99+ elapsed_time=$((elapsed_time + POLL_INTERVAL))
100+
101+ # Exit if the maximum wait time is exceeded
102+ if [[ "$elapsed_time" -ge "$MAX_WAIT_TIME" ]]; then
103+ echo "Timed out waiting for CI checks to complete."
104+ exit 1
105+ fi
106+ done
107+
108+ # Final check: Ensure all CI checks passed
109+ if [[ "$ALL_CHECKS_PASSED" == false ]]; then
110+ echo "One or more CI checks failed. Aborting merge."
111+ exit 1
112+ fi
113+
114+ echo "All CI checks passed successfully."
115+
116+
117+ - name : Check Target Branch and PR Title
118+ id : check_branch
119+ run : |
120+ PR_TITLE='${{ github.event.pull_request.title }}'
121+ echo "Original PR Title: $PR_TITLE"
122+
123+ # Escape problematic quotes
124+ ESCAPED_TITLE=$(echo "$PR_TITLE" | sed 's/"/\\"/g')
125+ echo "Escaped PR Title: $ESCAPED_TITLE"
126+
127+ if [[ "$ESCAPED_TITLE" =~ ([0-9]+\.[0-9]+\.[0-9]+).*to.*([0-9]+\.[0-9]+\.[0-9]+) ]]; then
128+ # Extract version numbers
129+ OLD_VERSION="${BASH_REMATCH[1]}"
130+ NEW_VERSION="${BASH_REMATCH[2]}"
131+ echo "Version change detected: $OLD_VERSION to $NEW_VERSION"
132+
133+ # Split version into major, minor, patch components
134+ OLD_MAJOR=$(echo "$OLD_VERSION" | cut -d '.' -f1)
135+ OLD_MINOR=$(echo "$OLD_VERSION" | cut -d '.' -f2)
136+ OLD_PATCH=$(echo "$OLD_VERSION" | cut -d '.' -f3)
137+
138+ NEW_MAJOR=$(echo "$NEW_VERSION" | cut -d '.' -f1)
139+ NEW_MINOR=$(echo "$NEW_VERSION" | cut -d '.' -f2)
140+ NEW_PATCH=$(echo "$NEW_VERSION" | cut -d '.' -f3)
141+
142+ # Check if it's a minor or patch update
143+ if [[ "$OLD_MAJOR" == "$NEW_MAJOR" ]] && [[ "$OLD_MINOR" == "$NEW_MINOR" ]] && [[ "$NEW_PATCH" -gt "$OLD_PATCH" ]]; then
144+ echo "Patch update detected"
145+ echo "should_merge=true" >> $GITHUB_ENV
146+ elif [[ "$OLD_MAJOR" == "$NEW_MAJOR" ]] && [[ "$NEW_MINOR" -gt "$OLD_MINOR" ]]; then
147+ echo "Minor update detected"
148+ echo "should_merge=true" >> $GITHUB_ENV
149+ else
150+ echo "No minor/patch update detected"
151+ echo "should_merge=false" >> $GITHUB_ENV
152+ fi
153+ else
154+ echo "No version change detected"
155+ echo "should_merge=false" >> $GITHUB_ENV
156+ fi
157+
158+ - name : Debug Context
159+ uses : actions/github-script@v6
160+ with :
161+ script : |
162+ console.log("Target branch:", context.payload.pull_request.base.ref);
163+
164+ - name : Check if Should Merge
165+ run : |
166+ echo "DEBUG: should_merge=${{ env.should_merge }}"
167+ if [[ "${{ env.should_merge }}" == "true" ]] && [[ "${{ github.event.pull_request.base.ref }}" == "Automatic_version_update_dependabot" ]]; then
168+ echo "DEBUG: should merge PR"
169+ echo "should_merge=true" >> $GITHUB_ENV
170+ else
171+ echo "DEBUG: skip merge"
172+ echo "should_merge=false" >> $GITHUB_ENV
173+ fi
174+
175+ - name : Merge Pull Request
176+ if : ${{ env.should_merge == 'true' }}
177+ uses : actions/github-script@v6
178+ with :
179+ script : |
180+ github.rest.pulls.merge({
181+ owner: context.repo.owner,
182+ repo: context.repo.repo,
183+ pull_number: context.payload.pull_request.number,
184+ merge_method: "squash"
185+ });
0 commit comments