Skip to content

ci: replace classic branch protection with a ruleset so the bypass works - #3481

Open
kevinjqliu wants to merge 4 commits into
apache:mainfrom
kevinjqliu:kevinjqliu-asf-yaml-ruleset-merge-gate
Open

kevinjqliu wants to merge 4 commits into
apache:mainfrom
kevinjqliu:kevinjqliu-asf-yaml-ruleset-merge-gate

Conversation

@kevinjqliu

@kevinjqliu kevinjqliu commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

What changes are included in this PR?

The breakglass from #3458 doesn't work yet. While classic branch protection exists, GitHub blocks the bypass even on an approved PR with green checks (DIRECT_MERGE: BLOCKED).

This replaces classic protection with Infra's "Default Branch Protection" ruleset (the template Infra rolled out across ASF repos), keeping the same rules. main then has two rulesets, and bypass is per ruleset:

Ruleset Rules Who can bypass
Default Branch Protection
  • Approval (required_approving_review_count: 1): changes go through a PR with at least 1 approval from a committer
  • Keep approvals (dismiss_stale_reviews: false): an approval still counts after new commits are pushed
  • Linear history (required_linear_history: true): no merge commits on main
  • No force push (restrict_force_push: true): nobody can rewrite main's history
  • No deletion (restrict_deletion: true): nobody can delete main
apache/root (ASF Infra) only
Merge Queue
  • Merge queue (type: merge_queue): PRs merge through the queue, tested against the latest main
  • Required checks (type: required_status_checks): CI must pass before merging
apache/root, iceberg-public (PRs only)

restrict_force_push and restrict_deletion aren't new: classic protection already blocked both (asfyaml sets allow_force_pushes: false, and GitHub blocks deletion by default). Rulesets don't, so they need to be listed.

A typical PR needs to pass both. Once a PR passes Default Branch Protection (it's approved), an iceberg-public member can bypass Merge Queue and merge without waiting for the queue or required checks.

Other projects did the same: Mahout hit the same bypass issue, and seatunnel uses protected_branches: ~.

Are these changes tested?

Validated with apache/infrastructure-asfyaml. After merge:

  • gh api repos/apache/iceberg-rust/branches/main --jq .protection.enabled should print false.
  • On an approved PR, viewerMergeActions should show DIRECT_MERGE: ALLOWED_WITH_BYPASS for an iceberg-public member.

AI Disclosure

Drafted with GitHub Copilot. Bypassing one ruleset while another applies to the same branch isn't explicitly documented by GitHub; apache/age's PG15 branch is the only Apache example I found.

Classic branch protection can only be bypassed by admins, and while it
exists GitHub blocks direct merges for the ruleset's bypass actors even
when every requirement is met. Move the approval, linear-history,
deletion and force-push rules into the Merge Queue ruleset and disable
classic protection, as apache/seatunnel does, so iceberg-public members
can use the breakglass. Requirements are otherwise unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 17:43
@kevinjqliu
kevinjqliu marked this pull request as draft October 16, 2026 17:44
kevinjqliu and others added 2 commits October 16, 2026 10:46
Put deletion, force-push, linear-history and approval rules in a separate
Branch Protection ruleset that only apache/root can bypass, so the
iceberg-public breakglass skips only the merge queue and required checks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@kevinjqliu kevinjqliu changed the title ci: move branch protection into the Merge Queue ruleset ci: replace classic branch protection with a ruleset so the bypass works Oct 16, 2026

This comment was marked as off-topic.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Comment thread .asf.yaml
type: branch
branches:
includes:
- "~DEFAULT_BRANCH"

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.

this refers to the same main branch as before

Comment thread .asf.yaml
Comment thread .asf.yaml
required_approving_review_count: 1
dismiss_stale_reviews: false

required_linear_history: true

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.

required_linear_history is not removed, still set to true in the default branch ruleset

Comment thread .asf.yaml
Comment thread .asf.yaml
Comment on lines +48 to +49
restrict_deletion: true
restrict_force_push: true

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.

newly added, to match the existing "classic protection" behavior (what protected_branches sets)

@kevinjqliu
kevinjqliu requested review from CTTY and blackmwk October 16, 2026 18:15
@kevinjqliu
kevinjqliu marked this pull request as ready for review October 16, 2026 18:15
@kevinjqliu

Copy link
Copy Markdown
Contributor Author

@CTTY @blackmwk im hoping this would get us the ability to bypass. I triple checked against other apache repo setting just to be sure

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants