Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions .github/actions/check-merge-queue/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: Check merge queue
description: Check whether a pull request can skip the merge queue when it's
up-to-date with the base branch.

inputs:
head-ref:
description: The name of the head ref (the pull request branch).
required: true
default: ${{ github.event.merge_group.head_ref }}

base-ref:
description: The name of the base ref (e.g., main, master).
required: true
default: main

github-token:
description: The GitHub token to use for authentication.
required: true
default: ${{ github.token }}

outputs:
up-to-date:
value: ${{ steps.up-to-date.outputs.up-to-date }}
description: Whether the pull request is up-to-date with the base branch
and is first in the merge queue, allowing it to skip the merge queue.

runs:
using: composite
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Get pull request details
id: pr-details
uses: actions/github-script@v8
env:
HEAD_REF: ${{ inputs.head-ref }}
with:
github-token: ${{ inputs.github-token }}
script: |
const { HEAD_REF } = process.env;
const match = HEAD_REF.match(/\/pr-([0-9]+)-/u);
if (!match) {
return core.setFailed(`Could not extract pull request number from head ref: "${HEAD_REF}".`);
}

const number = parseInt(match[1], 10);
const result = await github.graphql(`
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
headRefName
mergeQueueEntry { position }
}
}
}
`, {
owner: context.repo.owner,
name: context.repo.repo,
number,
});

if (!result.repository.pullRequest) {
return core.setFailed(`Pull request #${number} not found in repository "${context.repo.owner}/${context.repo.repo}".`);
}

const position = result.repository.pullRequest.mergeQueueEntry?.position;
if (!position) {
return core.setFailed(`Pull request #${number} is not in the merge queue.`);
}

core.setOutput('pr-number', number);
core.setOutput('pr-branch', result.repository.pullRequest.headRefName);
core.setOutput('merge-queue-position', position);

- name: Check if pull request is up-to-date with base branch
id: up-to-date
shell: bash
env:
BASE_REF: ${{ inputs.base-ref }}
PR_BRANCH: ${{ steps.pr-details.outputs.pr-branch }}
MERGE_QUEUE_POSITION: ${{ steps.pr-details.outputs.merge-queue-position }}
run: |
set -euo pipefail
if git merge-base --is-ancestor "origin/${BASE_REF}" "origin/${PR_BRANCH}" && [ "${MERGE_QUEUE_POSITION}" -eq 1 ]; then
echo "up-to-date=true" >> "$GITHUB_OUTPUT"
else
echo "up-to-date=false" >> "$GITHUB_OUTPUT"
fi
37 changes: 34 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,28 @@ concurrency:
cancel-in-progress: ${{ !contains(github.ref, 'refs/heads/main') }}

jobs:
check-skip-merge-queue:
name: Check if pull request can skip merge queue
if: github.event_name == 'merge_group'
runs-on: ubuntu-latest
outputs:
skip-merge-queue: ${{ steps.check-skip-merge-queue.outputs.up-to-date }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Check pull request merge queue status
id: check-skip-merge-queue
uses: ./.github/actions/check-merge-queue
with:
head-ref: ${{ github.event.merge_group.head_ref }}
base-ref: main
github-token: ${{ secrets.GITHUB_TOKEN }}

check-workflows:
name: Check workflows
needs:
- check-skip-merge-queue
if: always() && github.event_name != 'merge_group' || needs.check-skip-merge-queue.outputs.skip-merge-queue != 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand All @@ -24,6 +44,14 @@ jobs:
run: ${{ steps.download-actionlint.outputs.executable }} -color
shell: bash

print-job-status:
needs: check-workflows
runs-on: ubuntu-latest
if: ${{ success() }}
steps:
- run: echo "${{ job.status }}"
shell: bash

analyse-code:
name: Analyse code
needs: check-workflows
Expand Down Expand Up @@ -127,11 +155,14 @@ jobs:
name: All jobs pass
if: ${{ always() }}
runs-on: ubuntu-latest
needs: all-jobs-complete
needs:
- all-jobs-complete
- check-skip-merge-queue
env:
PASSED: ${{ needs.all-jobs-complete.outputs.passed == 'true' || needs.check-skip-merge-queue.outputs.skip-merge-queue == 'true' }}
steps:
- name: Check that all jobs have passed
run: |
passed="${{ needs.all-jobs-complete.outputs.passed }}"
if [[ $passed != "true" ]]; then
if [[ "$PASSED" != "true" ]]; then
exit 1
fi
Loading