From ae7647ba219de6ab594b063d199c16276a8eafce Mon Sep 17 00:00:00 2001 From: mengw15 <125719918+mengw15@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:07:40 -0700 Subject: [PATCH 1/3] ci: give GitHub Actions bypass on the release-branch ruleset 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 (#8377). People and PATs still face every rule. --- .asf.yaml | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/.asf.yaml b/.asf.yaml index 8e2adbc6a72..e507867bff7 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -76,13 +76,63 @@ github: ref_name: exclude: [] include: + # Release branches carry these same rules in "Merge Queue + # (release)" below — a separate ruleset because its Actions + # bypass must not extend to main. - "~DEFAULT_BRANCH" + rules: + - type: deletion + - type: non_fast_forward + - type: merge_queue + parameters: + merge_method: SQUASH + max_entries_to_build: 2 + min_entries_to_merge: 2 + max_entries_to_merge: 5 + min_entries_to_merge_wait_minutes: 3 + grouping_strategy: HEADGREEN + check_response_timeout_minutes: 45 + - type: pull_request + parameters: + allowed_merge_methods: + - squash + dismiss_stale_reviews_on_push: false + require_code_owner_review: false + require_last_push_approval: false + required_approving_review_count: 1 + required_review_thread_resolution: true + - type: required_linear_history + - type: required_status_checks + parameters: + strict_required_status_checks_policy: false + required_status_checks: + - context: Required Checks + - context: Check License Headers + - context: Validate PR title + + # Rule-for-rule identical to "Merge Queue" above; split out so the bypass + # below stays off main. The bypass exempts actions performed as the GitHub + # Actions app — i.e. any workflow's GITHUB_TOKEN, which is what + # 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. + - name: "Merge Queue (release)" + target: branch + enforcement: active + conditions: + ref_name: + exclude: [] + include: # Merge queue rules do NOT support wildcard ref patterns, so # release branches must be listed explicitly (not release/*). # Add each release line here as it is cut. - "refs/heads/release/v1.1" - "refs/heads/release/v1.2" - "refs/heads/release/v1.3" + bypass_actors: + # The GitHub Actions app. + - actor_id: 15368 + actor_type: Integration + bypass_mode: always rules: - type: deletion - type: non_fast_forward From c9e29545a491bbd8df4667b6e1a196bcf93aa9f4 Mon Sep 17 00:00:00 2001 From: mengw15 <125719918+mengw15@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:32:48 -0700 Subject: [PATCH 2/3] ci: create the release ruleset before shrinking the main one 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. --- .asf.yaml | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/.asf.yaml b/.asf.yaml index e507867bff7..f45f86ec250 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -69,17 +69,35 @@ github: rebase: false rulesets: - - name: Merge Queue + # Rule-for-rule identical to "Merge Queue" below; split out so the bypass + # here stays off main. The bypass exempts actions performed as the GitHub + # Actions app — i.e. any workflow's GITHUB_TOKEN, which is what + # 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 + # file order, so this one is created before that one stops covering the + # release branches. If GitHub rejects this ruleset, the apply aborts with + # the old protections fully intact; the failure order never leaves the + # release branches uncovered. + - name: "Merge Queue (release)" target: branch enforcement: active conditions: ref_name: exclude: [] include: - # Release branches carry these same rules in "Merge Queue - # (release)" below — a separate ruleset because its Actions - # bypass must not extend to main. - - "~DEFAULT_BRANCH" + # Merge queue rules do NOT support wildcard ref patterns, so + # release branches must be listed explicitly (not release/*). + # Add each release line here as it is cut. + - "refs/heads/release/v1.1" + - "refs/heads/release/v1.2" + - "refs/heads/release/v1.3" + bypass_actors: + # The GitHub Actions app. + - actor_id: 15368 + actor_type: Integration + bypass_mode: always rules: - type: deletion - type: non_fast_forward @@ -110,29 +128,17 @@ github: - context: Check License Headers - context: Validate PR title - # Rule-for-rule identical to "Merge Queue" above; split out so the bypass - # below stays off main. The bypass exempts actions performed as the GitHub - # Actions app — i.e. any workflow's GITHUB_TOKEN, which is what - # 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. - - name: "Merge Queue (release)" + - name: Merge Queue target: branch enforcement: active conditions: ref_name: exclude: [] include: - # Merge queue rules do NOT support wildcard ref patterns, so - # release branches must be listed explicitly (not release/*). - # Add each release line here as it is cut. - - "refs/heads/release/v1.1" - - "refs/heads/release/v1.2" - - "refs/heads/release/v1.3" - bypass_actors: - # The GitHub Actions app. - - actor_id: 15368 - actor_type: Integration - bypass_mode: always + # Release branches carry these same rules in "Merge Queue + # (release)" above — a separate ruleset because its Actions + # bypass must not extend to main. + - "~DEFAULT_BRANCH" rules: - type: deletion - type: non_fast_forward From 582d9f626426b1e958226c0a372b1bc9418dcf40 Mon Sep 17 00:00:00 2001 From: mengw15 <125719918+mengw15@users.noreply.github.com> Date: Thu, 3 Sep 2026 08:32:48 -0700 Subject: [PATCH 3/3] ci: push backports with GITHUB_TOKEN so the ruleset bypass applies The fast path has pushed with AUTO_MERGE_TOKEN since #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. --- .github/workflows/direct-backport-push.yml | 25 ++++++++++++++++------ .github/workflows/required-checks.yml | 3 +++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/direct-backport-push.yml b/.github/workflows/direct-backport-push.yml index b67fcc90fc0..585f4efceab 100644 --- a/.github/workflows/direct-backport-push.yml +++ b/.github/workflows/direct-backport-push.yml @@ -22,7 +22,8 @@ on: - main permissions: - actions: read + # write: the fast path dispatches Required Checks after its push (below). + actions: write checks: read contents: write issues: write @@ -356,11 +357,12 @@ jobs: uses: actions/checkout@v7 with: fetch-depth: 0 - # Use AUTO_MERGE_TOKEN (fine-grained PAT) so the push to the release - # branch retriggers workflows on that branch. GITHUB_TOKEN-authored - # pushes are excluded from triggering downstream workflows, which - # silences post-merge CI on backport commits. - token: ${{ secrets.AUTO_MERGE_TOKEN || secrets.GITHUB_TOKEN }} + # Push with the default GITHUB_TOKEN: the release rulesets admit the + # GitHub Actions app as a bypass actor, while a PAT-authored push is + # evaluated as that person and rejected. A GITHUB_TOKEN push starts + # no downstream workflows, so the step after the cherry-pick + # dispatches Required Checks itself — workflow_dispatch runs are the + # documented exception that GITHUB_TOKEN may create. - name: Cherry-pick merge commit onto target branch id: cherry_pick env: @@ -571,6 +573,17 @@ jobs: log "new_sha=${new_sha}" echo "new_sha=${new_sha}" >> "$GITHUB_OUTPUT" + - name: Run Required Checks on the pushed release branch + if: success() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_BRANCH: ${{ matrix.target }} + run: | + # The GITHUB_TOKEN push above starts no push-triggered workflows; + # dispatch the run the release branch would otherwise have gotten. + gh workflow run required-checks.yml \ + --repo "${GITHUB_REPOSITORY}" --ref "refs/heads/${TARGET_BRANCH}" + - name: Annotate original PR and commit on success if: success() uses: actions/github-script@v9 diff --git a/.github/workflows/required-checks.yml b/.github/workflows/required-checks.yml index 1db8a52668e..7b5e2214b15 100644 --- a/.github/workflows/required-checks.yml +++ b/.github/workflows/required-checks.yml @@ -22,6 +22,9 @@ on: branches: - 'main' - 'release/**' + # The backport fast path pushes release branches with GITHUB_TOKEN, which + # starts no push-triggered runs; it dispatches this workflow instead. + workflow_dispatch: pull_request: types: - opened