Skip to content

ci: give GitHub Actions bypass on the release-branch ruleset - #8379

Open
mengw15 wants to merge 6 commits into
apache:mainfrom
mengw15:ci/8377-actions-bypass-release-ruleset
Open

ci: give GitHub Actions bypass on the release-branch ruleset#8379
mengw15 wants to merge 6 commits into
apache:mainfrom
mengw15:ci/8377-actions-bypass-release-ruleset

Conversation

@mengw15

@mengw15 mengw15 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

The Merge Queue ruleset requires every change into release/* to arrive as a PR with one approving review, green required checks, and a pass through the merge queue. Right for people — but it also blocks direct-backport-push.yml, whose fast path pushes clean cherry-picks; every such push has been rejected since 2026-07-24, and five backports were silently lost (#8377).

This splits the ruleset in two, rule-for-rule identical: Merge Queue keeps ~DEFAULT_BRANCH, and a new Merge Queue (release) carries the three release branches plus a bypass_actors entry for the GitHub Actions app (actor_id: 15368). The split exists because a bypass is ruleset-wide — kept in one ruleset, it would let workflows push main too.

Scope, stated precisely: the bypass exempts actions performed as the Actions app — any workflow's GITHUB_TOKEN, not just the backport workflow, since rulesets cannot scope a bypass to one workflow. People and PATs still face every rule on every branch; main gets no bypass; force pushes and branch deletion stay blocked for everyone, Actions included, by Default Branch Protection.

Ordering inside the file is load-bearing: asfyaml applies rulesets in file order, so Merge Queue (release) is created before Merge Queue stops covering the release branches. If GitHub rejects the new ruleset, the apply aborts with today's protections fully intact — no failure path leaves the release branches uncovered.

The bypass alone would not revive the fast path: since #4676 the push job checked out with AUTO_MERGE_TOKEN, so GitHub evaluated its pushes as that PAT's owner — every pre-ruleset direct push shows a person as the pusher — and an Actions-app bypass would not cover them. The push job now uses the default GITHUB_TOKEN, which the bypass does cover, and dispatches Required Checks on the pushed branch explicitly, since a GITHUB_TOKEN push starts no push-triggered runs while workflow_dispatch is the documented exception that always creates one. The conflict path keeps the PAT: it pushes unprotected backport/* branches, where the opened PR's CI must still trigger.

Any related issues, documentation, discussions?

Closes #8377. #8378 took the PR-plus-auto-merge route to the same problem and is closed in favor of trying the bypass first. What lands on a release branch through this path is still only a cherry-pick of a commit that passed main's full CI and, once #8096 lands, its release manager's approving review.

How was this PR tested?

.asf.yaml and the workflows parse, and the structural check is now committed instead of run once: .github/scripts/test_asf_rulesets.sh (picked up by build.yml's glob-discovered infra tests) asserts the two rulesets' rules blocks stay deep-equal and that .asf.yaml and every workflow parse under a duplicate-key-strict loader, with PyYAML pinned in amber/dev-requirements.txt — the file the infra job installs; every failure path (duplicate key, rules drift, bypass on main, bypass tampered, missing PyYAML) was verified red before trusting the green. asfyaml treats a ruleset carrying target/rules/bypass_actors as a raw payload and forwards it verbatim (_RAW_RULESET_KEYS in feature/github/rulesets.py; its upstream tests assert the POST payload carries bypass_actors).

What cannot be proven before merge is GitHub accepting the Actions app as a bypass actor on this org: the same payload on a personal repository is rejected with "Actor GitHub Actions integration must be part of the ruleset source or owner organization", and no ASF repository uses an Integration bypass actor yet — hence the fail-safe ordering above. After Infra applies the merged file, GET /repos/apache/texera/rulesets should list Merge Queue (release); if it does not, the apply failed closed and nothing changed. The next clean backport is the end-to-end test.

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

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

@github-actions github-actions Bot added the ci changes related to CI label Sep 3, 2026
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @Yicong-Huang
    You can notify them by mentioning @Yicong-Huang in a comment.

@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.02%. Comparing base (1cbe857) to head (6bae0ba).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8379      +/-   ##
============================================
- Coverage     94.03%   94.02%   -0.01%     
+ Complexity     4821     4819       -2     
============================================
  Files          1204     1204              
  Lines         48991    48991              
  Branches       5956     5956              
============================================
- Hits          46067    46065       -2     
- Misses         1458     1459       +1     
- Partials       1466     1467       +1     
Flag Coverage Δ
access-control-service 81.00% <ø> (ø)
agent-service 99.32% <ø> (ø)
amber 89.90% <ø> (-0.02%) ⬇️
computing-unit-managing-service 73.67% <ø> (ø)
config-service 87.12% <ø> (ø)
file-service 87.91% <ø> (ø)
frontend 96.79% <ø> (ø)
notebook-migration-service 83.57% <ø> (ø)
pyamber 98.47% <ø> (ø)
workflow-compiling-service 77.19% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The backport workflow prefers a PAT, so the Actions integration bypass will not unblock its pushes.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Splits branch rulesets so GitHub Actions can bypass merge-queue requirements on release branches without bypassing main.

Changes:

  • Restricts the existing ruleset to the default branch.
  • Adds an equivalent release ruleset with an Actions integration bypass.
File summaries
File Description
.asf.yaml Separates release protections and adds the bypass.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .asf.yaml Outdated
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 2 better · 🔴 4 worse · ⚪ 9 noise (<±5%) · 0 without baseline

Compared against main 1cbe857 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 389 0.237 24,179/34,225/34,225 us 🔴 +15.9% / 🔴 +109.6%
🟢 bs=100 sw=10 sl=64 814 0.497 120,425/146,841/146,841 us 🟢 -6.4% / 🔴 +33.1%
bs=1000 sw=10 sl=64 923 0.564 1,081,968/1,140,629/1,140,629 us ⚪ within ±5% / 🔴 +8.3%
Baseline details

Latest main 1cbe857 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 389 tuples/sec 437 tuples/sec 749.39 tuples/sec -11.0% -48.1%
bs=10 sw=10 sl=64 MB/s 0.237 MB/s 0.267 MB/s 0.457 MB/s -11.2% -48.2%
bs=10 sw=10 sl=64 p50 24,179 us 24,013 us 13,045 us +0.7% +85.4%
bs=10 sw=10 sl=64 p95 34,225 us 29,524 us 16,328 us +15.9% +109.6%
bs=10 sw=10 sl=64 p99 34,225 us 29,524 us 19,518 us +15.9% +75.3%
bs=100 sw=10 sl=64 throughput 814 tuples/sec 827 tuples/sec 968.07 tuples/sec -1.6% -15.9%
bs=100 sw=10 sl=64 MB/s 0.497 MB/s 0.505 MB/s 0.591 MB/s -1.6% -15.9%
bs=100 sw=10 sl=64 p50 120,425 us 118,917 us 103,330 us +1.3% +16.5%
bs=100 sw=10 sl=64 p95 146,841 us 156,887 us 110,305 us -6.4% +33.1%
bs=100 sw=10 sl=64 p99 146,841 us 156,887 us 121,264 us -6.4% +21.1%
bs=1000 sw=10 sl=64 throughput 923 tuples/sec 925 tuples/sec 998 tuples/sec -0.2% -7.5%
bs=1000 sw=10 sl=64 MB/s 0.564 MB/s 0.565 MB/s 0.609 MB/s -0.2% -7.4%
bs=1000 sw=10 sl=64 p50 1,081,968 us 1,076,833 us 1,009,354 us +0.5% +7.2%
bs=1000 sw=10 sl=64 p95 1,140,629 us 1,137,554 us 1,052,748 us +0.3% +8.3%
bs=1000 sw=10 sl=64 p99 1,140,629 us 1,137,554 us 1,081,982 us +0.3% +5.4%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,514.49,200,128000,389,0.237,24179.14,34224.69,34224.69
1,100,10,64,20,2457.30,2000,1280000,814,0.497,120424.75,146840.89,146840.89
2,1000,10,64,20,21658.29,20000,12800000,923,0.564,1081967.51,1140628.99,1140628.99

@mengw15
mengw15 requested a review from Yicong-Huang September 3, 2026 15:55

@Yicong-Huang Yicong-Huang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 2 must-fix · 4 advisory · 0 polish: the design holds up, but a duplicate on: key stops Required Checks from starting.

Correctness (3)

  • .github/workflows/required-checks.yml:27: duplicate workflow_dispatch: key, the workflow fails at startup (must-fix, see inline)
  • .github/workflows/direct-backport-push.yml:576: a dispatch failure reports a landed backport as failed (must-fix, see inline)
  • .github/workflows/direct-backport-push.yml:585: qualified --ref where the API documents a bare branch name (advisory, see inline)

Design & architecture (1)

  • .asf.yaml:101: the rules: block is duplicated with nothing keeping the two copies equal (advisory, see inline)

Simplifications (1)

  • .github/workflows/direct-backport-push.yml:26: actions: write is workflow-wide where one step needs it (advisory, see inline)

Conventions (1)

  • .asf.yaml:72: no linked fork proof run for the workflow changes (advisory, see inline)
Verification trace

I checked the three load-bearing claims against the tree. After the split, Merge Queue covers only ~DEFAULT_BRANCH, so the bypass does not reach main. Default Branch Protection still carries restrict_deletion and restrict_force_push over release/* with only apache/root bypassing, so Actions can fast-forward a release branch but cannot delete or rewrite one. The two rules: blocks are deep-equal today, which makes the duplication a drift risk rather than a present bug.

On the startup failure: yaml.safe_load parses required-checks.yml clean, because PyYAML accepts a redefined key and keeps the last. That is why a local parse check could not catch this while GitHub's loader rejects it.

Comment thread .github/workflows/required-checks.yml Outdated
Comment thread .github/workflows/direct-backport-push.yml
Comment thread .github/workflows/direct-backport-push.yml Outdated
Comment thread .asf.yaml
Comment thread .github/workflows/direct-backport-push.yml Outdated
Comment thread .asf.yaml

rulesets:
- name: Merge Queue
# Rule-for-rule identical to "Merge Queue" below; split out so the bypass

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Advisory:

The PR-level gates ask a CI or workflow change to link a proof run, usually on a fork. The description explains why the ruleset half cannot be proven pre-merge, and that reasoning holds. The workflow half is fork-provable, and a fork run of Required Checks is exactly what would have surfaced the startup failure above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dispatch mechanism is the documented GITHUB_TOKEN exception ("workflow_dispatch and repository_dispatch events always create workflow runs"), and after 1864bda a surprise there degrades to a warning rather than a failed job. The .asf.yaml half only takes effect where Infra applies it — the body's post-merge verification covers that. Happy to stage a fork demo if you'd still like one.

Splits the Merge Queue ruleset in two, rules identical, so the release
half can carry a bypass for the Actions app without extending it to
main. Workflows (GITHUB_TOKEN) can then push release/* again, which
revives direct-backport-push.yml's fast path, rejected by the ruleset
since 2026-07-24 (apache#8377). People and PATs still face every rule.
asfyaml applies rulesets in file order. With the new ruleset listed
first, a rejected creation aborts the apply while today's protections
still cover the release branches; the old order would shrink "Merge
Queue" first and leave them uncovered if the creation then failed.
The fast path has pushed with AUTO_MERGE_TOKEN since apache#4676, so GitHub
evaluates that push as the PAT's owner, whom the Actions-app bypass
does not cover. Pushing with the default GITHUB_TOKEN puts it under
the bypass; the release-branch CI the PAT existed to retrigger is
dispatched explicitly instead, which workflow_dispatch permits a
GITHUB_TOKEN to do.
required-checks.yml already carried workflow_dispatch at the bottom of
its trigger block, so the added one was a duplicate key -- PyYAML keeps
the last silently, GitHub's loader rejects the file. The explanatory
comment moves to the existing key instead.

The dispatch after a fast-path push is now best-effort with a warning:
the backport has landed by then, and a failed dispatch would otherwise
trip the failure reporter into claiming the backport was lost. The ref
uses the documented bare branch form, and actions: write shrinks from
the workflow to the one job whose step dispatches.
The two Merge Queue rulesets are one policy split so the release half
can hold an Actions bypass that must not reach main; nothing else kept
the copies equal. The same script parses .asf.yaml and every workflow
with a duplicate-key-strict loader, the class of error a plain parse
passes and GitHub's loader rejects.
@mengw15
mengw15 force-pushed the ci/8377-actions-bypass-release-ruleset branch from 582d9f6 to 711265b Compare September 4, 2026 16:05

@Yicong-Huang Yicong-Huang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 4 resolved · 2 open · 3 new (3 new = 3 newly introduced · 0 late catches)

All four findings from the last round are fixed, verified in the tree. The committed check that answers the fifth cannot run in CI.

Correctness (1)

  • .github/scripts/test_asf_rulesets.sh:40import yaml with no PyYAML in the infra job; both legs die and Required Checks goes red (must-fix, see inline)

Design & architecture (1)

  • .github/scripts/test_asf_rulesets.sh:85 — the check guards rules equality but not the bypass placement the split exists for (advisory, replied on the .asf.yaml:101 thread)

Polish: 1 quick touch-up (see inline comments).

Still open from last round: the .asf.yaml rules: duplication has no working guard until the above is fixed, and no fork proof run is linked.

Verification trace

I checked each prior finding against the tree rather than the replies. grep -n workflow_dispatch .github/workflows/required-checks.yml returns one hit, line 35, so the duplicate on: key is gone. The dispatch at direct-backport-push.yml:595-598 is now if ! gh workflow run … ; then echo "::warning::…"; fi, so a failure no longer skips the success annotation at line 600, and --ref passes the bare branch name. The workflow-level map is back to actions: read and the new job-level block is complete: enumerating every API call inside push-backports gives repos.createCommitStatus, repos.createCommitComment, issues.createComment and actions.listJobsForWorkflowRun, with no pulls.* or checks.* call, so dropping pull-requests: write and checks: read for that job denies it nothing.

On the new script: it passes locally, where PyYAML happens to be installed, printing OK: 24 files duplicate-key clean; Merge Queue rules identical. In CI it never reaches that line.

Comment thread .github/scripts/test_asf_rulesets.sh
Comment thread .github/workflows/direct-backport-push.yml Outdated
The infra job's only Python install is amber/dev-requirements.txt, and
setup-python ships no PyYAML, so the new invariant check died on import
in both legs -- the constraint release_branches.py already records.
The check now also asserts what the split exists for: no bypass_actors
on "Merge Queue", exactly the Actions app on "Merge Queue (release)".
@github-actions github-actions Bot added dependencies Pull requests that update a dependency file pyamber labels Sep 4, 2026

@Yicong-Huang Yicong-Huang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 3 resolved · 1 open · 2 new (2 new = 2 newly introduced · 0 late catches)

The PyYAML must-fix is closed and the assertion block reaches CI for the first time on this head. Two small things left.

Design & architecture (1)

  • .asf.yaml:78: ruleset order is declared load-bearing, and nothing asserts it (advisory, see inline)

Polish: 1 quick touch-up (see inline comments).

Still open from last round: no fork proof run is linked for the dispatch step (the .asf.yaml:72 thread).

Verification trace

I checked the fix in the tree rather than in the reply. amber/dev-requirements.txt:43 pins pyyaml==6.0.3, build.yml:1289-1290 installs that file in the same job whose find at build.yml:1303 discovers the script, and build / infra is green on both ubuntu-latest and macos-latest at this head, so the assertion block executed for the first time.

A green assertion proves nothing until it can go red, so I replayed the block at test_asf_rulesets.sh:82-103 against mutated copies of the live .asf.yaml. Changing one merge_queue parameter on "Merge Queue" gives "rules differ", adding bypass_actors to "Merge Queue" gives "main has bypass", and both appending a second actor and deleting the release bypass give "release bypass wrong". All four failure paths the new assertions claim are real.

The dispatch runs the ref's own copy of the workflow, so I fetched required-checks.yml from apache/texera at release/v1.1, release/v1.2 and release/v1.3. All three already declare workflow_dispatch:, so the fast path works on the existing release lines without waiting for this PR to be backported.

Comment thread .asf.yaml
# direct-backport-push.yml's fast path pushes with (#8377). It cannot be
# scoped to a single workflow. People and PATs still face every rule.
#
# Listed BEFORE "Merge Queue" deliberately: asfyaml applies rulesets in

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Advisory:

This comment makes file order load-bearing and names the failure mode. The one check that would catch a reorder cannot see order: test_asf_rulesets.sh:77 keys the rulesets into a dict. Both the rules-equality and the new bypass-placement assertions then run on an order-free view, so an edit that alphabetises the rulesets stays green while removing the fail-safe. Asserting that "Merge Queue (release)" precedes "Merge Queue" is a two-line addition beside test_asf_rulesets.sh:93.


# Required by `bin/local-dev.sh -i` (the interactive Textual TUI).
textual==8.2.8
# .github/scripts/test_asf_rulesets.sh (infra job shell tests)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Polish:

Every other comment and pin group in this file is blank-line separated (:22, :27, :31, :35, :39). This entry reads as part of the textual group.

Suggested change
# .github/scripts/test_asf_rulesets.sh (infra job shell tests)
# .github/scripts/test_asf_rulesets.sh (infra job shell tests)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci changes related to CI dependencies Pull requests that update a dependency file pyamber

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backport fast path has been dead since 2026-07-24: direct pushes to release/* are rejected by the ruleset

4 participants