Dependabot Automerge #106
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Dependabot Automerge | |
| on: | |
| workflow_run: | |
| workflows: | |
| - CI | |
| - E2E Backend Integration Tests | |
| - E2E Controller Tests | |
| - E2E Gateway Tests | |
| types: | |
| - completed | |
| permissions: | |
| actions: read | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| automerge: | |
| if: > | |
| github.event.workflow_run.event == 'pull_request' && | |
| github.event.workflow_run.conclusion == 'success' && | |
| github.event.workflow_run.pull_requests[0].number != null | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Load current pull request state | |
| id: pr | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| pr_json="$(gh pr view "$PR_NUMBER" --repo "$REPO" --json author,autoMergeRequest,headRefOid,isDraft,state,url)" | |
| author="$(jq -r '.author.login // ""' <<<"$pr_json")" | |
| state="$(jq -r '.state' <<<"$pr_json")" | |
| is_draft="$(jq -r '.isDraft' <<<"$pr_json")" | |
| head_sha="$(jq -r '.headRefOid' <<<"$pr_json")" | |
| pr_url="$(jq -r '.url' <<<"$pr_json")" | |
| auto_merge_enabled="$(jq -r 'if .autoMergeRequest == null then "false" else "true" end' <<<"$pr_json")" | |
| echo "Evaluating PR #$PR_NUMBER from author $author" | |
| # Dependabot PRs may be reported either as the bot user or the | |
| # GitHub App, depending on which API surface returns the author. | |
| case "$author" in | |
| "dependabot[bot]"|"app/dependabot") | |
| ;; | |
| *) | |
| echo "skip_reason=not_dependabot" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| ;; | |
| esac | |
| if [ "$state" != "OPEN" ] || [ "$is_draft" != "false" ]; then | |
| echo "skip_reason=not_open_ready" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [ "$auto_merge_enabled" = "true" ]; then | |
| echo "skip_reason=auto_merge_already_enabled" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "head_sha=$head_sha" >> "$GITHUB_OUTPUT" | |
| echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT" | |
| - name: Verify all PR test workflows passed | |
| id: checks | |
| if: steps.pr.outputs.head_sha != '' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| HEAD_SHA: ${{ steps.pr.outputs.head_sha }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| # Keep this list aligned with the pull request workflows so merges wait | |
| # for the full test suite on the current PR head commit. | |
| required_workflows=( | |
| "CI" | |
| "E2E Backend Integration Tests" | |
| "E2E Controller Tests" | |
| "E2E Gateway Tests" | |
| ) | |
| runs_json="$(gh api "/repos/$REPO/actions/runs?event=pull_request&head_sha=$HEAD_SHA&per_page=100")" | |
| all_passed=true | |
| for workflow in "${required_workflows[@]}"; do | |
| workflow_run="$(jq -c --arg workflow "$workflow" ' | |
| [.workflow_runs[] | select(.name == $workflow)] | |
| | sort_by(.created_at, .run_attempt) | |
| | last | |
| ' <<<"$runs_json")" | |
| if [ "$workflow_run" = "null" ]; then | |
| echo "Workflow \"$workflow\" has not reported a run for $HEAD_SHA yet." | |
| all_passed=false | |
| continue | |
| fi | |
| status="$(jq -r '.status' <<<"$workflow_run")" | |
| conclusion="$(jq -r '.conclusion // ""' <<<"$workflow_run")" | |
| if [ "$status" != "completed" ] || [ "$conclusion" != "success" ]; then | |
| echo "Workflow \"$workflow\" is $status with conclusion \"$conclusion\"." | |
| all_passed=false | |
| fi | |
| done | |
| echo "all_passed=$all_passed" >> "$GITHUB_OUTPUT" | |
| - name: Enable merge for the pull request | |
| if: steps.checks.outputs.all_passed == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| HEAD_SHA: ${{ steps.pr.outputs.head_sha }} | |
| PR_URL: ${{ steps.pr.outputs.pr_url }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| for attempt in 1 2 3; do | |
| echo "Attempt $attempt to enable merge for $PR_URL" | |
| if gh pr merge "$PR_URL" --repo "$REPO" --auto --squash --match-head-commit "$HEAD_SHA"; then | |
| exit 0 | |
| fi | |
| pr_state="$(gh pr view "$PR_URL" --repo "$REPO" --json state,autoMergeRequest)" | |
| state="$(jq -r '.state' <<<"$pr_state")" | |
| auto_merge_enabled="$(jq -r 'if .autoMergeRequest == null then "false" else "true" end' <<<"$pr_state")" | |
| if [ "$state" = "MERGED" ] || [ "$auto_merge_enabled" = "true" ]; then | |
| echo "Merge was applied despite the previous CLI error." | |
| exit 0 | |
| fi | |
| if [ "$attempt" -lt 3 ]; then | |
| sleep $((attempt * 5)) | |
| fi | |
| done | |
| echo "Failed to enable merge for $PR_URL after retries." | |
| exit 1 |