Repository navigation
Name both mixing functions in lineDigest's comment (#1077) #633
Workflow file for this run
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: Merge gate | |
| # The mechanical half of the merge gates in AGENTS.md (section "Merge gates"): a queue entry is | |
| # refused when its pull request carries `hold`, or when the newest conclusive text at the head about | |
| # to be merged is INC / REQUEST_CHANGES. `.github/scripts/merge-gate.mjs` does the judging. | |
| # | |
| # Two events, two jobs in one. On `merge_group` it judges: `review-gate.yml` reports a tip when it | |
| # changes, and #610 shows why that is not a gate — its report ran at 10:31:08Z and the INC landed at | |
| # 11:24:37Z, 54 minutes later. So the judgement happens at the moment that is audited, against the head | |
| # SHA the queue is about to merge, re-read live, and a refusal fails the job. | |
| # | |
| # On `pull_request` it reports instead, and never fails. A check listed as required must also produce a | |
| # result on the pull request head, or every pull request reads "Expected — waiting for status" and | |
| # cannot enter the queue at all (#639). It cannot fail there either: a verdict arrives as a comment, | |
| # which starts no `pull_request` run, so a red report would outlive the INC it named until the next | |
| # push. The refused ones are named in the summary; the queue entry refuses for real. | |
| # | |
| # The required status check is the **job name**, `merge-gate` — not the workflow name `Merge gate`. | |
| # A ruleset that lists `Merge gate` requires a context no run ever produces. | |
| # | |
| # A `merge_group` event carries no pull request, no labels and no reviews. Only `head_ref` | |
| # (`gh-readonly-queue/main/pr-<N>-<sha>`, passed fully qualified as `refs/heads/...`) points at them, | |
| # and its <sha> is the entry's BASE (`merge_group.base_sha`), not the pull request head; the entry's own | |
| # commit is `merge_group.head_sha`. So the script parses N back out, judges the pull request's live | |
| # head exactly as the `pull_request` run does, and asks the | |
| # API. Reading a review's `state` never works: the account cannot approve its own pull requests, so its | |
| # reviews stay `COMMENTED` even for an INC — the INC on #610 was a comment, not a review. | |
| # | |
| # Read-only: no secrets, nothing written, and the script and the review policy are taken from the base | |
| # commit of the group, never from the pull request's own code. | |
| on: | |
| merge_group: | |
| pull_request: | |
| concurrency: | |
| group: merge-gate-${{ github.event.merge_group.head_sha || github.event.pull_request.head.sha }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| issues: read | |
| pull-requests: read | |
| jobs: | |
| merge-gate: | |
| name: merge-gate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ github.event.merge_group.base_sha || github.event.pull_request.base.sha }} | |
| path: base | |
| persist-credentials: false | |
| - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | |
| with: | |
| node-version: 24 | |
| # #914: a pull request built on an old copy of main re-uploads whole files, and the work main | |
| # merged after the branch was cut disappears while CI stays green — the deletion is the pull | |
| # request (#887 deleted #869's 84 test lines the same hour; #907 deleted #909's fix 40 minutes | |
| # after it merged, mergeable with tests-ok green). Its own checkout of the head, full history: | |
| # the rule needs merge-base(origin/main, HEAD) and the commits main added after it. | |
| # The script still comes from `base`, so a pull request cannot change the check that judges it. | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| if: github.event_name == 'pull_request' | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| path: head | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| # Report only: a finding is a Reviewer's read, never a red check (#914's own scope), so it | |
| # cannot fail the job, and it stays out of branch protection and out of tests-ok's needs. | |
| - name: Report work main merged that this pull request deletes | |
| if: github.event_name == 'pull_request' | |
| continue-on-error: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| PR: ${{ github.event.pull_request.number }} | |
| run: | | |
| git -C head fetch --no-tags --quiet origin +refs/heads/main:refs/remotes/origin/main | |
| # The pull request that adds this script has no base copy yet, so that one run uses its own | |
| # (read-only, same fallback review-gate.yml documents). Once the base has it, the base wins. | |
| script=base/.github/scripts/silent-revert.mjs | |
| [ -f "$script" ] || script=head/.github/scripts/silent-revert.mjs | |
| node "$script" --repo-dir head | |
| # The script and the policy come from the base commit, so a pull request cannot weaken the gate | |
| # that judges it. On `pull_request` that also means the base copy may be older than this | |
| # workflow and refuse for lack of a conclusion — never fail the check over that: the report is | |
| # informational, and the queue entry re-reads with the code it will actually merge. | |
| - name: Judge the queue entry, or report on the pull request | |
| continue-on-error: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| GH_REPO: ${{ github.repository }} | |
| HEAD_REF: ${{ github.event.merge_group.head_ref }} | |
| BASE_SHA: ${{ github.event.merge_group.base_sha }} | |
| ENTRY_SHA: ${{ github.event.merge_group.head_sha }} | |
| PR: ${{ github.event.pull_request.number }} | |
| MODE: ${{ github.event_name == 'pull_request' && 'report' || 'queue' }} | |
| run: node base/.github/scripts/merge-gate.mjs |