You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit b771962
Browse filesBrowse the repository at this point in the historyBrowse files
ci(api-review-gate): publish the gate as a commit status
The gate's merge context was its job name, which inherits two GitHub
behaviours that together make it both unenforceable and self-poisoning.
A required *job* that skips counts as PASSED by branch protection, so
any path that skips the evaluating job hands out a free pass — the hole
that let fork PRs merge with e2e never run (#3257). And check runs are
not deduplicated per name: every workflow run gets its own check suite,
so `GET /commits/{sha}/check-runs?filter=latest` returns the same set as
`filter=all`, and the rollup is worst-of. Two runs on one head SHA
therefore leave two verdicts standing for one context name, and a
cancelled run poisons the context until the next push. Commit statuses
are deduplicated per context, newest wins.
Rename the evaluating job off the gate context and publish "API Review
Gate" as a commit status: `api-gate-report` for same-repo PRs, and a
privileged workflow_run for forks, whose GITHUB_TOKEN is read-only on
both the pull_request and the pull_request_review trigger and so can
never post a status itself. Skipped and cancelled runs post nothing, so
declining to post can only ever preserve a verdict some real run
reached — it can never invent one.
That invariant is what makes it safe to stop re-evaluating on the plain
`commented` reviews the review bots post: such a review cannot move a
verdict that counts only APPROVED reviews, and the run that skips now
leaves the previous status untouched instead of overwriting it.
Also split the concurrency group so a run that computes no verdict
cannot cancel one that does. A bot commenting during the ~30s
evaluation used to cancel it and then contribute nothing, leaving a
cancelled run as that SHA's only api-gate verdict (41d1153, 4b1966c).
For the gate to actually block a merge, main branch protection must
require the "API Review Gate" status context; until then it is
advisory, as the job name was.
Assisted-by: LLM
Signed-off-by: Myasnikov Daniil <[email protected]>
echo "::error::This PR makes a sizeable API change (new group, new resource, or breaking change) and needs an approving review from one of: ${API_OWNERS}. See the job summary for details."
163
225
exit 1
226
+
227
+
# Publish the required "API Review Gate" commit status. Separate from the
228
+
# evaluating job for the reasons in the header: the gate must not be a job
229
+
# name, and a run that reached no verdict must post nothing.
230
+
#
231
+
# The `if` guard stays in LOCKSTEP with the evaluating job's — this job runs if
232
+
# and only if that one does. A `commented` review skips both, so the previous
233
+
# real status stands untouched. `!cancelled()` rather than `always()`: a run
234
+
# killed by the concurrency group has no verdict, and posting one anyway would
235
+
# overwrite a green status with red — the exact failure #3262 hit twice with
236
+
# "E2E Tests" (see its `e2e-report`).
237
+
#
238
+
# Fork PRs skip this job. Their GITHUB_TOKEN is read-only on BOTH the
239
+
# `pull_request` and `pull_request_review` triggers, so no run of this workflow
240
+
# can post a status for a fork; api-review-gate-fork.yaml concludes the context
241
+
# for them from a privileged workflow_run. Until it does, the required status is
242
+
# unposted and the fork PR is not mergeable — fail-closed by construction.
0 commit comments