Skip to content

Commit

Permalink
Merge pull request #128817 from Homebrew/automerge-on-approval
Browse files Browse the repository at this point in the history
workflows: publish approved PRs on CI completion
  • Loading branch information
carlocab authored Apr 20, 2023
2 parents 250bbde + b763256 commit 1d607f6
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 0 deletions.
172 changes: 172 additions & 0 deletions .github/workflows/automerge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
name: automerge

on:
workflow_run:
workflows:
- CI
- Track approved PRs
types:
- completed

concurrency:
group: automerge-${{ github.event.workflow_run.event }}-${{ github.event.workflow_run.pull_requests[0].number || github.event.workflow_run.id }}
cancel-in-progress: true

env:
HOMEBREW_DEVELOPER: 1
HOMEBREW_NO_AUTO_UPDATE: 1
GH_REPO: ${{ github.repository }}
GH_NO_UPDATE_NOTIFIER: 1
GH_PROMPT_DISABLED: 1

jobs:
status-check:
runs-on: ubuntu-latest
if: >
github.repository_owner == 'Homebrew' &&
github.event.workflow_run.conclusion == 'success' &&
(github.event.workflow_run.event == 'pull_request' ||
github.event.workflow_run.name != 'CI')
outputs:
pull-number: ${{ steps.pr.outputs.number }}
approved: ${{ steps.approval-status.outputs.approved }}
complete: ${{ steps.approval-status.outputs.complete }}
mergeable: ${{ steps.approval-status.outputs.mergeable }}
permissions:
contents: read
pull-requests: read
actions: read
steps:
- name: Download `pull-number` artifact
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WORKFLOW_ID: ${{ github.event.workflow_run.id }}
run: gh run download --name pull-number "$WORKFLOW_ID"

- run: echo "number=$(cat number)" >> "$GITHUB_OUTPUT"
id: pr

- name: Check PR labels
id: check-labels
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ steps.pr.outputs.number }}
run: |
publishable=yes
while IFS='' read -r label
do
if [[ "$label" = "do not merge" ]] ||
[[ "$label" = "new formula" ]] ||
[[ "$label" = "automerge-skip" ]] ||
[[ "$label" = "CI-published-bottle-commits" ]]
then
publishable=no
break
fi
done < <(
gh api \
--header 'Accept: application/vnd.github+json' \
--header 'X-GitHub-Api-Version: 2022-11-28' \
"repos/$GH_REPO/pulls/$PR" \
--jq '.labels[].name'
)
echo "publishable=$publishable" >> "$GITHUB_OUTPUT"
- name: Get approval and CI status
if: steps.check-labels.outputs.publishable == 'yes'
id: approval-status
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ steps.pr.outputs.number }}
run: |
attempt=0
max_attempts=5
timeout=5
while [[ "$attempt" -lt "$max_attempts" ]]
do
attempt=$(( attempt + 1 ))
approved=false
complete=false
mergeable=false
review_data="$(
gh api \
--header 'Accept: application/vnd.github+json' \
--header 'X-GitHub-Api-Version: 2022-11-28' \
"repos/$GH_REPO/pulls/$PR/reviews"
)"
if jq --exit-status 'any(.[].state; .== "APPROVED")' <<< "$review_data" &&
jq --exit-status 'all(.[].state; .!= "CHANGES_REQUESTED" )' <<< "$review_data"
then
approved=true
fi
if gh pr checks "$PR"
then
complete=true
fi
pr_data="$(
gh api \
--header 'Accept: application/vnd.github+json' \
--header 'X-GitHub-Api-Version: 2022-11-28' \
"repos/$GH_REPO/pulls/$PR"
)"
mergeable_state="$(jq --raw-output .mergeable_state <<< "$pr_data")"
draft="$(jq --raw-output .draft <<< "$pr_data")"
# See https://github.com/octokit/octokit.net/issues/1763 for possible values.
if [[ "$draft" = "false" ]] && [[ "$mergeable_state" = "clean" ]]
then
mergeable=true
fi
if [[ "$approved" = "true" ]] &&
[[ "$complete" = "true" ]] &&
[[ "$mergeable" = "true" ]] ||
[[ "$attempt" -eq "$max_attempts" ]]
then
break
fi
echo "::notice ::PR #$PR status:"
echo "::notice ::Approved? $approved"
echo "::notice ::CI Complete? $complete"
echo "::notice ::Mergeable? $mergeable"
echo "::notice ::Checking again in ${timeout}s..."
sleep "$timeout"
timeout=$(( timeout * 2 ))
done
{
echo "approved=$approved"
echo "complete=$complete"
echo "mergeable=$mergeable"
} >> "$GITHUB_OUTPUT"
merge:
runs-on: ubuntu-latest
needs: status-check
if: >
fromJson(needs.status-check.outputs.approved) &&
fromJson(needs.status-check.outputs.complete) &&
fromJson(needs.status-check.outputs.mergeable)
container:
image: ghcr.io/homebrew/ubuntu22.04:master
permissions:
contents: read
pull-requests: read
actions: write # to dispatch publish workflow
defaults:
run:
shell: bash
steps:
- name: Set up Homebrew
uses: Homebrew/actions/setup-homebrew@master

- run: brew pr-publish "$PR"
env:
HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR: ${{ needs.status-check.outputs.pull-number }}
22 changes: 22 additions & 0 deletions .github/workflows/reviews.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Track approved PRs

on:
pull_request_review:
types: [submitted]

jobs:
record_pull_number:
if: >
github.repository_owner == 'Homebrew' &&
github.event.review.state == 'approved'
runs-on: ubuntu-latest
steps:
- name: Save pull request number
run: |
mkdir -p pr
echo '${{ github.event.pull_request.number }}' > pr/number
- uses: actions/upload-artifact@v3
with:
name: pull-number
path: pr
16 changes: 16 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ jobs:
TESTING_FORMULAE: ${{ steps.formulae-detect.outputs.testing_formulae }}
run: brew test-bot --only-bottles-fetch --testing-formulae="$TESTING_FORMULAE"

record_pull_number:
if: github.repository_owner == 'Homebrew' && github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Save pull request number
env:
PR: ${{github.event.number}}
run: |
mkdir -p pr
echo "$PR" > pr/number
- uses: actions/upload-artifact@v3
with:
name: pull-number
path: pr

setup_tests:
permissions:
pull-requests: read
Expand Down

0 comments on commit 1d607f6

Please sign in to comment.