Skip to content

Check if PR is automergeable #20619

Check if PR is automergeable

Check if PR is automergeable #20619

name: Check if PR is automergeable
# Triggered on all PRs by
# - completion of CI checks (status events), OR
# - tagging with "automerge" or "automerge-web" labels, OR
# - updates to current PRs
#
# This workflow checks if the PR that invoked the trigger is automergeable.
# A PR is automergeable iff it:
# 1) is labeled "automerge" OR "automerge-web" (originates from web submission) (checked in actions_helpers.py)
# 2) only changes plugins (subdirs of /benchmarks, /data, /models, /metrics)
# 3) passes all tests (Travis and Jenkins).
# If all 3 conditions are met, the "automerge-approved" label is applied to the PR
# (This label triggers the `automerge_plugin-only_prs` workflow to merge the PR.)
#
# If any test fails, the user will be notified by the brain-score email account.
# If the user has already been notified of a test failure and there have been no pushes to the PR, no email will be sent.
on:
pull_request:
types: [labeled, synchronize]
status:
permissions: write-all
jobs:
check_trigger:
name: Check what triggered this workflow. If it was the addition of a 'failure-notified' label, skip the rest of workflow.
runs-on: ubuntu-latest
outputs:
PROCEED: ${{ steps.check_label.outputs.PROCEED }}
steps:
- name: Check trigger condition
id: check_label
run: |
if [[ "${{ github.event_name }}" == "pull_request" && "${{ github.event.action }}" == "labeled" ]]; then
LABEL_NAME="${{ github.event.label.name }}"
echo "Trigger label: $LABEL_NAME"
if [[ "$LABEL_NAME" == "failure-notified" ]]; then
echo "PROCEED=false" >> $GITHUB_OUTPUT
else
echo "PROCEED=true" >> $GITHUB_OUTPUT
fi
else
echo "PROCEED=true" >> $GITHUB_OUTPUT
fi
remove_failure_notified_label:
name: On new push, remove the 'failure-notified' label.
if: ${{ (github.event_name == 'pull_request') && (github.event.action == 'synchronize') }}
runs-on: ubuntu-latest
steps:
- name: Remove 'failure-notified' label on new push to PR
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prNumber = context.payload.pull_request.number;
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
if (labels.find(label => label.name === 'failure-notified')) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
name: 'failure-notified'
});
}
check_pr_details:
name: Check all details of the PR (if all tests have passed, PR meets automerge conditions, pr number, label is 'automerge-web')
runs-on: ubuntu-latest
needs: check_trigger
if: needs.check_trigger.outputs.PROCEED == 'true'
outputs:
ALL_TESTS_PASS: ${{ steps.get_test_results.outputs.TEST_RESULTS }}
PR_NUMBER: ${{ steps.get_pr_number.outputs.PR_NUMBER }}
AUTOMERGE_WEB: ${{ steps.check_automerge_web_label.outputs.AUTOMERGE_WEB }}
steps:
- name: Check out repository code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get PR number from workflow context
id: get_pr_number
run: |
echo "PR_NUMBER=$( python brainscore_vision/submission/actions_helpers.py get_pr_num )" >> $GITHUB_OUTPUT
- name: Check if PR has 'automerge-web' label
id: check_automerge_web_label
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
LABELS_JSON=$(gh pr view ${{ steps.get_pr_number.outputs.PR_NUMBER }} --json labels)
echo "Labels: $LABELS_JSON"
if echo "$LABELS_JSON" | jq -e '.labels[] | select(.name == "automerge-web")' >/dev/null; then
echo "Found automerge-web label."
echo "AUTOMERGE_WEB=true" >> $GITHUB_OUTPUT
else
echo "automerge-web label not found."
echo "AUTOMERGE_WEB=false" >> $GITHUB_OUTPUT
fi
- name: Get test results and ensure automergeable
id: get_test_results
run: |
echo "Checking test results for PR head $( python brainscore_vision/submission/actions_helpers.py get_pr_head )"
test_results=$( python brainscore_vision/submission/actions_helpers.py )
echo $test_results
echo "TEST_RESULTS=$test_results" >> $GITHUB_OUTPUT
approve_automerge:
name: If tests pass and PR is automergeable, apply "approve_automerge" label to PR
runs-on: ubuntu-latest
permissions:
issues: write
needs: [check_pr_details, check_trigger]
if: needs.check_pr_details.outputs.ALL_TESTS_PASS == 'True' && needs.check_trigger.outputs.PROCEED == 'true'
steps:
- name: Check out repository code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Add automerge-approved label to PR
env:
GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ needs.check_pr_details.outputs.PR_NUMBER }}
LABELS: automerge-approved
run: gh issue edit "$NUMBER" --add-label "$LABELS"
check_email_label:
name: Check if user has already been notified of failure
runs-on: ubuntu-latest
needs: [check_pr_details, check_trigger]
outputs:
FAILURE_NOTIFIED: ${{ steps.check_failure_notified_label.outputs.FAILURE_NOTIFIED }}
if: needs.check_pr_details.outputs.ALL_TESTS_PASS == 'False' && needs.check_pr_details.outputs.AUTOMERGE_WEB == 'true' && needs.check_trigger.outputs.PROCEED == 'true'
steps:
- name: Check out repository code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check if PR has 'failure-notified' label already
id: check_failure_notified_label
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
LABELS_JSON=$(gh pr view ${{ needs.check_pr_details.outputs.PR_NUMBER }} --json labels)
echo "Labels: $LABELS_JSON"
if echo "$LABELS_JSON" | jq -e '.labels[] | select(.name == "failure-notified")' >/dev/null; then
echo "Found failure-notified label."
echo "FAILURE_NOTIFIED=true" >> $GITHUB_OUTPUT
else
echo "failure-notified label not found."
echo "FAILURE_NOTIFIED=false" >> $GITHUB_OUTPUT
fi
notify_failure:
name: If any test fails and failure hasn't been notified, notify the user through the brain-score email account (only needed for web submissions)
uses: ./.github/workflows/user_notification_system.yml
needs: [check_pr_details, check_email_label, check_trigger]
if: needs.check_pr_details.outputs.ALL_TESTS_PASS == 'False' && needs.check_pr_details.outputs.AUTOMERGE_WEB == 'true' && (needs.check_email_label.outputs.FAILURE_NOTIFIED == 'false') && (needs.check_trigger.outputs.PROCEED == 'true')
with:
pr_number: ${{ needs.check_pr_details.outputs.PR_NUMBER }}
is_automerge_web: true
action_type: 'send_email'
secrets: inherit