Repository navigation
Take the state lock on the next write, not on a poll (#1027) #860
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: Enqueue guard | ||
|
Check warning on line 1 in .github/workflows/enqueue-guard.yml
|
||
| # The required check on the code fork's `main` (#812). `enqueue-guard.mjs` was only a script an agent ran | ||
| # before merging; this writes its decision onto the pull request head as a check run named | ||
| # `enqueue-guard`, and the ruleset on `main` (`bypass_actors: []`) requires it — so an unreviewed pull | ||
| # request cannot be squash-merged through the API at all, instead of being refused only by a script | ||
| # somebody remembered to run. | ||
| # | ||
| # Why `pull_request_target` and not `pull_request`: a `pull_request` job from a fork gets a read-only | ||
| # `GITHUB_TOKEN` and could not write the check for the head it judges, while a required context that is | ||
| # never produced leaves that pull request on "Expected" forever (#639). `pull_request_target` runs with the | ||
| # write token this workflow declares, and it takes its code from `main` — `ref: main` below is the only | ||
| # checkout, no pull request code is ever fetched or run, and the head is read through the API | ||
| # (docs/autonomous-dev.md → Limits of GITHUB_TOKEN). The comment body a verdict arrives in is only parsed. | ||
| # | ||
| # The events are the ones that can change the answer for a fixed head: a push (a new head, whose old PASS | ||
| # no longer names it), a label added or removed (`agent-pr`, `hold`), a comment or a review body (a | ||
| # `Verdict:`), and a manual run. Each one re-judges the live head and PATCHes the same check run, so the | ||
| # check turns green without a new commit and back red when the tip moves. | ||
| # | ||
| # #960 (A'): `merge_group` is the one event where this decision can become a required context of the queue | ||
| # itself — the merge queue does not read this check today, so `merge-gate` is still the only gate on an | ||
| # entry. The run takes the entry's commit and the queue branch, judges the pull request through the same | ||
| # `decidePull`, and writes the check on the entry commit; nothing here changes the required contexts. | ||
| on: | ||
| pull_request_target: | ||
| types: [opened, synchronize, reopened, labeled, unlabeled, ready_for_review] | ||
| pull_request_review: | ||
| types: [submitted, edited, dismissed] | ||
| issue_comment: | ||
| types: [created, edited, deleted] | ||
| merge_group: | ||
| workflow_dispatch: | ||
| inputs: | ||
| pr: | ||
| description: 'Pull request number to judge' | ||
| required: true | ||
| type: string | ||
| # One judgement per pull request at a time: a label and a comment can arrive together, and two runs | ||
| # alternating the same check run is a state no one can read. | ||
| concurrency: | ||
| group: enqueue-guard-${{ github.event.pull_request.number || github.event.issue.number || github.event.merge_group.head_sha || github.run_id }} | ||
| cancel-in-progress: true | ||
| # `checks: write` is what creates the required context — the same write token `pass-label.yml` already | ||
| # uses for labels on `issue_comment`. Everything else is read-only, and nothing here needs a secret. | ||
| permissions: | ||
| contents: read | ||
| issues: read | ||
| pull-requests: read | ||
| checks: write | ||
| jobs: | ||
| judge: | ||
| # A comment on a plain issue is not a pull request; the manual run names the pull request itself. | ||
| name: judge | ||
| if: github.event_name != 'issue_comment' || github.event.issue.pull_request != null | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| ref: main | ||
| persist-credentials: false | ||
| - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 | ||
| with: | ||
| node-version: 24 | ||
| # The judgement is `enqueue-guard.mjs`'s own; this only writes it. A refusal is a red check run, not | ||
| # a red job: the gate is the check, and a failing job would report the same refusal twice. | ||
| - name: Judge the head and write its enqueue-guard check run | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| GH_REPO: ${{ github.repository }} | ||
| PR: ${{ github.event.pull_request.number || github.event.issue.number || inputs.pr }} | ||
| # #960 (A'): a merge_group event carries no PR number, only the queue branch and the entry | ||
| # commit, and the check has to sit on the commit the queue merges. | ||
| HEAD_REF: ${{ github.event.merge_group.head_ref }} | ||
| ENTRY_SHA: ${{ github.event.merge_group.head_sha }} | ||
| run: node .github/scripts/gate-check.mjs | ||