The GitHub Actions job "Required Checks" on 
texera.git/gh-readonly-queue/main/pr-8096-16a70cd5a6ea48c87baee7d8b9fe8e17ca10a71a
 has failed.
Run started by GitHub user Yicong-Huang (triggered by Yicong-Huang).

Head commit for run:
48da91c6048f4365a514d1a180f6e51685dbf649 / Meng Wang <[email protected]>
ci: block the merge until each release/* label has its manager's approval 
(#8096)

### What changes were proposed in this PR?

A `fix:` PR into `main` is auto-labeled with every actively-supported
`release/*` branch, and the label alone decides the backport: whatever
is labeled at merge time gets cherry-picked to the release branch,
whether or not that branch's release manager has looked at it. The
review request #6940 added is advisory only.

Worse than the missing gate is what it does to the record. A manager who
does not want a fix on their branch declines by staying silent, so the
label stays on. The PR merges carrying `release/v1.2`, nothing is
backported there, and months later that label says the fix shipped in
1.2 when it did not.

This makes the approval **required to merge**. `Backport Approvals` is
red while any `release/*` label on the PR lacks its manager's approval.
Declining becomes an action rather than silence: the manager removes
their branch's label, which clears the check for that branch. Since the
merge waits for every remaining label to be approved, **the labels on a
merged PR are exactly the branches Direct Backport Push then sends the
fix to** — true by construction, not by anyone remembering to tidy up.

The rule: managers gate their own branch and nothing else, so each
decides alone — but the merge waits for all of them, so a fix cannot
land on v1.2 while v1.3 is still undecided. `COMMENTED` reviews never
change an approval, and a later `CHANGES_REQUESTED` or `DISMISSED`
revokes one; any dismissal lands on `DISMISSED`, so that state proves an
approval is not standing, never what the dismissed review had been. A
manager who wrote the fix counts as approving it, since GitHub does not
let anyone approve their own PR. An entry that omits `manager` stays
ungated, but a label naming a branch `release-branches.yml` does not
list at all is held back — retiring a branch means dropping its entry
while its label lives on, and nobody is then designated to approve it.
An unreadable review list holds every gated target back rather than
guessing.

`no-backport-needed` is reported as a contradiction rather than settled
in its own favour. It says the fix reaches no release branch, but
nothing removes the `release/*` labels it overrides, and `precheck.yml`
documents adding it mid-review — by which point the auto-labeler has
applied them. Passing the check there would merge a PR carrying a label
promising a backport the push skips: the false record this exists to
prevent. Removing either the label or the veto clears it.

### Where the required context is registered

`Backport Approvals` is registered in **its own ruleset, scoped to
`~DEFAULT_BRANCH`** — deliberately not in the Merge Queue ruleset, whose
`ref_name.include` also covers `refs/heads/release/v1.1`, `v1.2` and
`v1.3`.

The workflow exists only on the default branch, and a `pull_request` run
takes its workflows from the merge ref — for a PR into `release/vX.Y`
that is the release-branch base plus a head branched from it, so neither
carries the file. The context would never be produced there, and a
required check that is never reported is not a red X but a permanent
"waiting for status": 17 PRs into `release/v1.2` are open right now,
nearly all draft backports this pipeline auto-opened on a conflict, and
each would have become unmergeable. Scoping it to the default branch
leaves them requiring exactly the three contexts they require today.

The Merge Queue ruleset's context list carries a comment saying so,
since that list sits beside the branch list a release manager edits when
cutting a new line.

### A second, smaller repair

`backport-auto-label.yml` checked out `base.sha` to read
`release-branches.yml`.
That is main's tip at the PR's last synchronize rather than now, so on a
PR whose
base predates #6941 — the commit that added the config — the file is
absent and
the step dies with a file-not-found. It has failed that way 20 times in
production since 2026-07-27, each time leaving that PR unlabeled. Its
checkout
now reads the default branch, the revision this PR's new check and
Direct
Backport Push already read, so all three judge a backport by one config.

That is the same failure this PR's own checkout is written to avoid, and
it is
worse here: an unlabeled PR can be fixed by hand, but a required context
that
dies on a missing file turns red for a reason its author cannot act on.

### Any related issues, documentation, discussions?

Closes #8084. Follow-on to #6940, which built this backport pipeline.

### How was this PR tested?

Proof runs on this PR, both paths exercised for real:

| | run | result |
| --- | --- | --- |
| labelled `release/v1.2`, unapproved |
[33723336875](https://github.com/apache/texera/actions/runs/33723336875)
| fails — `BLOCKED release/v1.2 — needs an approving review from
@xuang7` |
| label removed (the decline action) |
[33723396801](https://github.com/apache/texera/actions/runs/33723396801)
| passes |
| no `release/*` label at all |
[33722853310](https://github.com/apache/texera/actions/runs/33722853310)
| passes — "nothing to approve", the case that must never block since
the context is required on every PR |

The decision logic was also driven through cases locally: both managers
approve, one approves, neither, an approval revoked by a dismissal, a
manager who authored the PR, an entry with no manager, a label naming a
branch absent from the config, an unreadable review list,
`no-backport-needed` alongside `release/*` labels, `no-backport-needed`
alone, and a PR based on a release branch. Each produced the expected
cleared/blocked split and the expected wording — including that a
dismissed review is never reported as a standing approval, and that
"could not read the reviews" is never reported as "nobody approved".

The workflow parses as YAML and its `github-script` body passes `node
--check`; `.asf.yaml` parses and its rulesets resolve to the intended
scopes; `release_branches.py` still parses the annotated config
unchanged.

Not covered locally: `merge_group` and `edited` triggers, and
`pulls.listReviews` pagination, first execute on GitHub.

**Rollout.** `.asf.yaml` is applied by ASF Infra after a merge to
`main`, so this PR is not itself gated by the new context — it takes
effect from the next PR. Two consequences worth knowing: pull requests
already open into `main` at the cutover show `Backport Approvals` as
"Expected" until some event (a push, a label, a review) triggers the
workflow on them; and reverting the one ruleset lifts the gate without
touching the workflow.

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (claude-opus-5)

Report URL: https://github.com/apache/texera/actions/runs/33911192618

With regards,
GitHub Actions via GitBox

Reply via email to