Skip to content

feat(github): add merge_queue convenience syntax for rulesets - #119

Open
rusackas wants to merge 1 commit into
apache:mainfrom
rusackas:feat/merge-queue-ruleset
Open

rusackas wants to merge 1 commit into
apache:mainfrom
rusackas:feat/merge-queue-ruleset

Conversation

@rusackas

Copy link
Copy Markdown
Member

Summary

GitHub's merge queue rule type already worked through the existing raw ruleset payload path (github.rulesets[].rules[].type: merge_queue) since the top-level schema for rulesets is fully generic and the numeric-parameter coercion list already happened to include all five of merge_queue's integer fields. But it wasn't documented anywhere, and it couldn't be combined with any of the convenience-syntax keys (required_pull_request_reviews, branches, etc.) in the same ruleset entry, since raw and convenience syntax are mutually exclusive per entry. A project wanting a merge queue alongside e.g. required reviews had to hand-write the entire ruleset as a raw API payload, translating branches.includes into conditions.ref_name, etc.

This PR:

  • Adds a merge_queue convenience key, so it composes with the rest of the convenience syntax (see example below).
  • Documents both the new convenience key and the (already-working) raw payload rule type in the README's Rulesets section.
  • Adds test coverage: convenience-syntax success, combining with another convenience rule, missing-field/invalid-enum validation errors, and a raw-passthrough regression test.

All seven merge_queue parameters are required by GitHub's Rulesets API, so the convenience syntax requires all of them too rather than guessing at undocumented defaults.

Example

github:
  rulesets:
    - name: "Merge Queue"
      type: branch
      required_pull_request_reviews:
        required_approving_review_count: 1
      merge_queue:
        check_response_timeout_minutes: 60
        grouping_strategy: ALLGREEN
        max_entries_to_build: 5
        max_entries_to_merge: 5
        merge_method: SQUASH
        min_entries_to_merge: 1
        min_entries_to_merge_wait_minutes: 5

Testing instructions

  • pytest tests/github_rulesets.py (new tests: test_rulesets_convenience_merge_queue_*, test_rulesets_raw_merge_queue_rule_passes_through)
  • ruff check / ruff format --check / mypy all pass on the changed files
  • Verified against a real strictyaml schema load + payload-build pass (not just unit-test mocks) that a merge_queue ruleset round-trips to the exact shape GitHub's Rulesets API expects

No behavior changes to any existing rule types.

Comment thread README.md
Comment on lines +922 to +925
- `grouping_strategy` must be `ALLGREEN` (all queued PRs in a group must pass checks) or `HEADGREEN` (only the head
commit of the group must pass checks).
- `merge_method` must be `MERGE`, `SQUASH`, or `REBASE`.
- `merge_queue` combines with the other convenience keys in the same ruleset entry, as in the example above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: these values might be more useful as comments in the example configuration (like in “Merge buttons” then as notes. This way the documentation travels with the example.

@potiuk

potiuk commented Sep 18, 2026

Copy link
Copy Markdown
Member

Tried to sandbox-test this and could not, but the reason isn't your change.

Rebased onto current main (the branch predates the --branch flag #127 added to asfyaml-run) and applied the README's example ruleset. GitHub rejected it:

Validation failed while creating ruleset 'Merge Queue': ["Invalid rule 'merge_queue': "]

I then posted the same rule directly to the REST API with a hand-written payload, bypassing the parser entirely, and got byte-identical output — while a plain pull_request ruleset creates fine on the same repository. So the payload your code builds isn't the problem; merge queue isn't available for a user-owned sandbox repo.

Run: https://github.com/potiuk/infrastructure-asfyaml/actions/runs/35316854577

This needs a run against apache/infrastructure-asfyaml-sandbox by a committer to be validated. Worth noting in docs/testing-a-change.md too — the fork self-testing path can't cover org-only features.

@rusackas

Copy link
Copy Markdown
Member Author

@potiuk any idea who's qualified to run that? Pretty sure I can't do it :/

@potiuk

potiuk commented Sep 22, 2026

Copy link
Copy Markdown
Member

@potiuk any idea who's qualified to run that? Pretty sure I can't do it :/

One of the infra people :)

@rusackas

Copy link
Copy Markdown
Member Author

Thanks @potiuk. @Humbedooh any chance you could kick off a sandbox run on this one? Merge queue isn't available on user-owned repos, so the fork self-test path can't cover it.

rusackas added a commit to apache/superset that referenced this pull request Sep 23, 2026
Adds a `github.rulesets` entry to .asf.yaml turning on GitHub's merge
queue for master, alongside the existing classic `protected_branches`
config (the two mechanisms coexist; classic protection still gates
PR-entry-into-queue readiness, the new ruleset adds the merge_queue
rule and its own required_status_checks that must pass against the
queue's synthetic merge-group ref before a batch actually merges).

Wires `merge_group:` support into every workflow that produces one of
those required checks, since GitHub does not run a workflow against a
merge-group ref unless it explicitly listens for that event -- without
this, every queued PR would time out waiting for statuses that never
get reported:

- enforce-single-migration-head.yml: the file-list-based skip
  optimization can't work for merge_group (no pull_request context to
  list files from), so it now always runs the real check there,
  matching the file's own existing fail-closed philosophy -- this is
  also exactly the scenario the check exists for (two migration heads
  that each looked fine alone, combined by the queue).
- pre-commit.yml: the changed-files diff base for merge_group is read
  from the event's own explicit `merge_group.base_sha` rather than
  assuming its commit has the same two-parent shape pull_request's
  synthetic merge commit does.
- scripts/change_detector.py (used by superset-frontend.yml,
  superset-e2e.yml, and all three python test workflows): the change
  detector's event-type dispatch previously raised on anything but
  pull_request/push/workflow_dispatch/schedule; added a merge_group
  branch that diffs against `merge_group.base_sha` via a new shared
  `fetch_changed_files_compare()` helper (also now used by the
  existing push path, no behavior change there).

Two required checks are deliberately left without merge_group support
and excluded from the new ruleset's required_status_checks, staying
required only via the existing classic config (i.e. still gate a PR
before a committer can add it to the queue, just don't re-run once
it's in one):

- lint-check: validates the PR's own title, which doesn't mean
  anything once re-run against a merge-group ref.
- dependency-review: actions/dependency-review-action has a confirmed,
  currently-unfixed bug on merge_group events (destructures
  github.event.pull_request, which doesn't exist there, and crashes --
  see actions/dependency-review-action#843).

Uses the raw ruleset payload syntax rather than the nicer `merge_queue`
convenience key, since that key is still pending upstream in
apache/infrastructure-asfyaml#119 (not yet merged/deployed as of this
writing) -- .asf.yaml can move to the convenience syntax once that
lands.

### TESTING INSTRUCTIONS

- `pytest tests/unit_tests/scripts/change_detector_test.py` -- 13
  passed (8 existing + 5 new: compare-helper delegation, push still
  delegates to it, merge_group happy path, merge_group fails closed
  without MERGE_GROUP_BASE_SHA).
- `ruff check` / `ruff format --check` on the two touched Python files
  -- clean.
- `zizmor` (the same GHA security linter this repo's `validate-all-ghas`
  check runs) against every touched workflow/action file -- no findings.
- `python3 -c "import yaml; yaml.safe_load(...)"` on .asf.yaml and
  every touched workflow file -- all parse.
- Parsed .asf.yaml back with PyYAML to confirm `rulesets` landed as a
  sibling of `protected_branches`, not nested inside it, and printed
  the parsed ruleset structure to confirm the exact shape GitHub's
  Rulesets API expects.
- Could not run pre-commit itself end-to-end -- its git-diffing is
  broken in this environment on an unrelated host xcrun/libxcrun
  architecture mismatch (not something this commit introduces); the
  checks above cover what pre-commit would have run for these file
  types (ruff, YAML validity, zizmor).
- Not yet verified against a live merge-group run (only checkable once
  this actually merges and a real queue entry exercises it).

### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@potiuk

potiuk commented Sep 23, 2026

Copy link
Copy Markdown
Member

As described in https://github.com/apache/infrastructure-asfyaml/blob/main/docs/testing-a-change.md#testing-locally-instead - you need an organisation admin and the organisation has to have ability to use that feature.

You could likely @rusackas test it yourself - and provide evidences (as I did) - all you need you need an organisation in GitHub that you can test it with -> Preset I guess?

The documentation is pretty comprehensive - and basically all I did when I tested other changes was to ask my agent to "test this PR" the SKILL that I created should handle all the rest, including producing test report and linking to your runs showing how it works.

rusackas added a commit to apache/superset that referenced this pull request Sep 23, 2026
Adds a `github.rulesets` entry to .asf.yaml turning on GitHub's merge
queue for master, alongside the existing classic `protected_branches`
config (the two mechanisms coexist; classic protection still gates
PR-entry-into-queue readiness, the new ruleset adds the merge_queue
rule and its own required_status_checks that must pass against the
queue's synthetic merge-group ref before a batch actually merges).

Wires `merge_group:` support into every workflow that produces one of
those required checks, since GitHub does not run a workflow against a
merge-group ref unless it explicitly listens for that event -- without
this, every queued PR would time out waiting for statuses that never
get reported:

- enforce-single-migration-head.yml: the file-list-based skip
  optimization can't work for merge_group (no pull_request context to
  list files from), so it now always runs the real check there,
  matching the file's own existing fail-closed philosophy -- this is
  also exactly the scenario the check exists for (two migration heads
  that each looked fine alone, combined by the queue).
- pre-commit.yml: the changed-files diff base for merge_group is read
  from the event's own explicit `merge_group.base_sha` rather than
  assuming its commit has the same two-parent shape pull_request's
  synthetic merge commit does.
- scripts/change_detector.py (used by superset-frontend.yml,
  superset-e2e.yml, and all three python test workflows): the change
  detector's event-type dispatch previously raised on anything but
  pull_request/push/workflow_dispatch/schedule; added a merge_group
  branch that diffs against `merge_group.base_sha` via a new shared
  `fetch_changed_files_compare()` helper (also now used by the
  existing push path, no behavior change there).

Two required checks are deliberately left without merge_group support
and excluded from the new ruleset's required_status_checks, staying
required only via the existing classic config (i.e. still gate a PR
before a committer can add it to the queue, just don't re-run once
it's in one):

- lint-check: validates the PR's own title, which doesn't mean
  anything once re-run against a merge-group ref.
- dependency-review: actions/dependency-review-action has a confirmed,
  currently-unfixed bug on merge_group events (destructures
  github.event.pull_request, which doesn't exist there, and crashes --
  see actions/dependency-review-action#843).

Uses the raw ruleset payload syntax rather than the nicer `merge_queue`
convenience key, since that key is still pending upstream in
apache/infrastructure-asfyaml#119 (not yet merged/deployed as of this
writing) -- .asf.yaml can move to the convenience syntax once that
lands.

### TESTING INSTRUCTIONS

- `pytest tests/unit_tests/scripts/change_detector_test.py` -- 13
  passed (8 existing + 5 new: compare-helper delegation, push still
  delegates to it, merge_group happy path, merge_group fails closed
  without MERGE_GROUP_BASE_SHA).
- `ruff check` / `ruff format --check` on the two touched Python files
  -- clean.
- `zizmor` (the same GHA security linter this repo's `validate-all-ghas`
  check runs) against every touched workflow/action file -- no findings.
- `python3 -c "import yaml; yaml.safe_load(...)"` on .asf.yaml and
  every touched workflow file -- all parse.
- Parsed .asf.yaml back with PyYAML to confirm `rulesets` landed as a
  sibling of `protected_branches`, not nested inside it, and printed
  the parsed ruleset structure to confirm the exact shape GitHub's
  Rulesets API expects.
- Could not run pre-commit itself end-to-end -- its git-diffing is
  broken in this environment on an unrelated host xcrun/libxcrun
  architecture mismatch (not something this commit introduces); the
  checks above cover what pre-commit would have run for these file
  types (ruff, YAML validity, zizmor).
- Not yet verified against a live merge-group run (only checkable once
  this actually merges and a real queue entry exercises it).

### ADDITIONAL INFORMATION
- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@rusackas

Copy link
Copy Markdown
Member Author

Ahh, didn't realize a Preset org would work for this. Not sure I've got owner rights there though. And I hadn't spotted the sandbox-test skill in .claude/skills before, neat.

@potiuk

potiuk commented Sep 23, 2026

Copy link
Copy Markdown
Member

SKILLs are all you need ;)

rusackas added a commit to apache/superset that referenced this pull request Sep 27, 2026
Adds a `github.rulesets` entry to .asf.yaml turning on GitHub's merge
queue for master, alongside the existing classic `protected_branches`
config (the two mechanisms coexist; classic protection still gates
PR-entry-into-queue readiness, the new ruleset adds the merge_queue
rule and its own required_status_checks that must pass against the
queue's synthetic merge-group ref before a batch actually merges).

Wires `merge_group:` support into every workflow that produces one of
those required checks, since GitHub does not run a workflow against a
merge-group ref unless it explicitly listens for that event -- without
this, every queued PR would time out waiting for statuses that never
get reported:

- enforce-single-migration-head.yml: the file-list-based skip
  optimization can't work for merge_group (no pull_request context to
  list files from), so it now always runs the real check there,
  matching the file's own existing fail-closed philosophy -- this is
  also exactly the scenario the check exists for (two migration heads
  that each looked fine alone, combined by the queue).
- pre-commit.yml: the changed-files diff base for merge_group is read
  from the event's own explicit `merge_group.base_sha` rather than
  assuming its commit has the same two-parent shape pull_request's
  synthetic merge commit does.
- scripts/change_detector.py (used by superset-frontend.yml,
  superset-e2e.yml, and all three python test workflows): the change
  detector's event-type dispatch previously raised on anything but
  pull_request/push/workflow_dispatch/schedule; added a merge_group
  branch that diffs against `merge_group.base_sha` via a new shared
  `fetch_changed_files_compare()` helper (also now used by the
  existing push path, no behavior change there).

Two required checks are deliberately left without merge_group support
and excluded from the new ruleset's required_status_checks, staying
required only via the existing classic config (i.e. still gate a PR
before a committer can add it to the queue, just don't re-run once
it's in one):

- lint-check: validates the PR's own title, which doesn't mean
  anything once re-run against a merge-group ref.
- dependency-review: actions/dependency-review-action has a confirmed,
  currently-unfixed bug on merge_group events (destructures
  github.event.pull_request, which doesn't exist there, and crashes --
  see actions/dependency-review-action#843).

Uses the raw ruleset payload syntax rather than the nicer `merge_queue`
convenience key, since that key is still pending upstream in
apache/infrastructure-asfyaml#119 (not yet merged/deployed as of this
writing) -- .asf.yaml can move to the convenience syntax once that
lands.

- `pytest tests/unit_tests/scripts/change_detector_test.py` -- 13
  passed (8 existing + 5 new: compare-helper delegation, push still
  delegates to it, merge_group happy path, merge_group fails closed
  without MERGE_GROUP_BASE_SHA).
- `ruff check` / `ruff format --check` on the two touched Python files
  -- clean.
- `zizmor` (the same GHA security linter this repo's `validate-all-ghas`
  check runs) against every touched workflow/action file -- no findings.
- `python3 -c "import yaml; yaml.safe_load(...)"` on .asf.yaml and
  every touched workflow file -- all parse.
- Parsed .asf.yaml back with PyYAML to confirm `rulesets` landed as a
  sibling of `protected_branches`, not nested inside it, and printed
  the parsed ruleset structure to confirm the exact shape GitHub's
  Rulesets API expects.
- Could not run pre-commit itself end-to-end -- its git-diffing is
  broken in this environment on an unrelated host xcrun/libxcrun
  architecture mismatch (not something this commit introduces); the
  checks above cover what pre-commit would have run for these file
  types (ruff, YAML validity, zizmor).
- Not yet verified against a live merge-group run (only checkable once
  this actually merges and a real queue entry exercises it).

- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
GitHub's merge queue rule type already worked through the raw
ruleset payload path (the numeric-parameter allowlist already
listed all five of its integer fields), but it wasn't documented
anywhere and couldn't be combined with the convenience-syntax keys
in the same ruleset entry, since raw and convenience syntax can't
mix. A project wanting merge queue plus e.g. required_pull_request_reviews
had to hand-write the entire ruleset as a raw payload.

Adds a `merge_queue` convenience key alongside the existing
required_status_checks/required_pull_request_reviews keys, so it
composes with the rest of the convenience syntax. All seven fields
are required by GitHub's Rulesets API, so validation requires all
of them rather than guessing at defaults GitHub doesn't document.

Documents both the new convenience key and the (already-working)
raw payload rule type in the Rulesets section of the README.
@rusackas
rusackas force-pushed the feat/merge-queue-ruleset branch from ad14f73 to 922b0de Compare October 2, 2026 03:35
rusackas added a commit to apache-superset/infrastructure-asfyaml-sandbox that referenced this pull request Oct 2, 2026
@rusackas

rusackas commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

Sandbox-tested at 922b0de (rebased onto current main — the branch predated #127's --branch flag on asfyaml-run, which the sandbox-test workflow requires).

Ran against apache-superset/infrastructure-asfyaml-sandbox (an org-owned repo — merge queue isn't available on a user-owned sandbox, which is why self-testing in a personal fork couldn't cover this). Applied:

github:
  rulesets:
    - name: "Merge Queue"
      type: branch
      required_pull_request_reviews:
        required_approving_review_count: 1
      merge_queue:
        check_response_timeout_minutes: 60
        grouping_strategy: ALLGREEN
        max_entries_to_build: 5
        max_entries_to_merge: 5
        merge_method: SQUASH
        min_entries_to_merge: 1
        min_entries_to_merge_wait_minutes: 5

Confirmed by reading /repos/apache-superset/infrastructure-asfyaml-sandbox/rulesets back afterward — a Merge Queue ruleset was created (enforcement: active, scoped to ~DEFAULT_BRANCH) containing a merge_queue rule with all 7 parameters matching exactly (merge_method: SQUASH, max_entries_to_build: 5, min_entries_to_merge: 1, max_entries_to_merge: 5, min_entries_to_merge_wait_minutes: 5, grouping_strategy: ALLGREEN, check_response_timeout_minutes: 60), combined correctly with the pull_request rule (required_approving_review_count: 1) from the same ruleset entry. As a bonus, the ruleset's own non_fast_forward/branch-protection rules then blocked a direct force-push I tried against the sandbox's main — confirming enforcement: active is genuinely active, not just reported.

Reset afterward: deleted the ruleset via the API (its own protection blocked the usual "push baseline, re-run" reset until it was gone), then re-ran against the baseline .asf.yaml to confirm nothing regenerates it. Rulesets list is back to empty, description back to baseline.

Dry run: https://github.com/rusackas/infrastructure-asfyaml/actions/runs/36967718339
Apply run: https://github.com/rusackas/infrastructure-asfyaml/actions/runs/36967773709
Reset run: https://github.com/rusackas/infrastructure-asfyaml/actions/runs/36967925281

@rusackas

rusackas commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

@potiuk sandbox test's done, details in the comment above. Had to use an apache-superset sandbox since merge queue needs an org-owned repo, exactly as you suspected. CI's green and it's already approved, so should be mergeable whenever you get a chance.

rusackas added a commit to apache/superset that referenced this pull request Oct 2, 2026
Adds a `github.rulesets` entry to .asf.yaml turning on GitHub's merge
queue for master, alongside the existing classic `protected_branches`
config (the two mechanisms coexist; classic protection still gates
PR-entry-into-queue readiness, the new ruleset adds the merge_queue
rule and its own required_status_checks that must pass against the
queue's synthetic merge-group ref before a batch actually merges).

Wires `merge_group:` support into every workflow that produces one of
those required checks, since GitHub does not run a workflow against a
merge-group ref unless it explicitly listens for that event -- without
this, every queued PR would time out waiting for statuses that never
get reported:

- enforce-single-migration-head.yml: the file-list-based skip
  optimization can't work for merge_group (no pull_request context to
  list files from), so it now always runs the real check there,
  matching the file's own existing fail-closed philosophy -- this is
  also exactly the scenario the check exists for (two migration heads
  that each looked fine alone, combined by the queue).
- pre-commit.yml: the changed-files diff base for merge_group is read
  from the event's own explicit `merge_group.base_sha` rather than
  assuming its commit has the same two-parent shape pull_request's
  synthetic merge commit does.
- scripts/change_detector.py (used by superset-frontend.yml,
  superset-e2e.yml, and all three python test workflows): the change
  detector's event-type dispatch previously raised on anything but
  pull_request/push/workflow_dispatch/schedule; added a merge_group
  branch that diffs against `merge_group.base_sha` via a new shared
  `fetch_changed_files_compare()` helper (also now used by the
  existing push path, no behavior change there).

Two required checks are deliberately left without merge_group support
and excluded from the new ruleset's required_status_checks, staying
required only via the existing classic config (i.e. still gate a PR
before a committer can add it to the queue, just don't re-run once
it's in one):

- lint-check: validates the PR's own title, which doesn't mean
  anything once re-run against a merge-group ref.
- dependency-review: actions/dependency-review-action has a confirmed,
  currently-unfixed bug on merge_group events (destructures
  github.event.pull_request, which doesn't exist there, and crashes --
  see actions/dependency-review-action#843).

Uses the raw ruleset payload syntax rather than the nicer `merge_queue`
convenience key, since that key is still pending upstream in
apache/infrastructure-asfyaml#119 (not yet merged/deployed as of this
writing) -- .asf.yaml can move to the convenience syntax once that
lands.

- `pytest tests/unit_tests/scripts/change_detector_test.py` -- 13
  passed (8 existing + 5 new: compare-helper delegation, push still
  delegates to it, merge_group happy path, merge_group fails closed
  without MERGE_GROUP_BASE_SHA).
- `ruff check` / `ruff format --check` on the two touched Python files
  -- clean.
- `zizmor` (the same GHA security linter this repo's `validate-all-ghas`
  check runs) against every touched workflow/action file -- no findings.
- `python3 -c "import yaml; yaml.safe_load(...)"` on .asf.yaml and
  every touched workflow file -- all parse.
- Parsed .asf.yaml back with PyYAML to confirm `rulesets` landed as a
  sibling of `protected_branches`, not nested inside it, and printed
  the parsed ruleset structure to confirm the exact shape GitHub's
  Rulesets API expects.
- Could not run pre-commit itself end-to-end -- its git-diffing is
  broken in this environment on an unrelated host xcrun/libxcrun
  architecture mismatch (not something this commit introduces); the
  checks above cover what pre-commit would have run for these file
  types (ruff, YAML validity, zizmor).
- Not yet verified against a live merge-group run (only checkable once
  this actually merges and a real queue entry exercises it).

- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@potiuk

potiuk commented Oct 5, 2026

Copy link
Copy Markdown
Member

cool. @Humbedooh -> there are a number of other PRs here as well, is there a way to get those reviews / merges done somewhat faster ? Generally speaking we now have tools that allow to test things in minutes (literally), so all we really need is somoene who has write access to decide if given feature should or should not be merged - and you can test it via your agent with:

test this PR

So I think all major blockers from quickly processing those PRs are gone? If the infrastructure team does not have enough capacity, I am sure there are a number of volunteers (starting with me) who would be happy to review and merge such requests (given some criteria that should be applied) - very similarly as we do with infrastructure-actions.

Can we do something to speed things up here and empower more PMCs to do more things with their actions?

I am not asking for "more work for you" - I am asking for ways to unblock obstacles - and I am oferring my help.

rusackas added a commit to apache/superset that referenced this pull request Oct 7, 2026
Adds a `github.rulesets` entry to .asf.yaml turning on GitHub's merge
queue for master, alongside the existing classic `protected_branches`
config (the two mechanisms coexist; classic protection still gates
PR-entry-into-queue readiness, the new ruleset adds the merge_queue
rule and its own required_status_checks that must pass against the
queue's synthetic merge-group ref before a batch actually merges).

Wires `merge_group:` support into every workflow that produces one of
those required checks, since GitHub does not run a workflow against a
merge-group ref unless it explicitly listens for that event -- without
this, every queued PR would time out waiting for statuses that never
get reported:

- enforce-single-migration-head.yml: the file-list-based skip
  optimization can't work for merge_group (no pull_request context to
  list files from), so it now always runs the real check there,
  matching the file's own existing fail-closed philosophy -- this is
  also exactly the scenario the check exists for (two migration heads
  that each looked fine alone, combined by the queue).
- pre-commit.yml: the changed-files diff base for merge_group is read
  from the event's own explicit `merge_group.base_sha` rather than
  assuming its commit has the same two-parent shape pull_request's
  synthetic merge commit does.
- scripts/change_detector.py (used by superset-frontend.yml,
  superset-e2e.yml, and all three python test workflows): the change
  detector's event-type dispatch previously raised on anything but
  pull_request/push/workflow_dispatch/schedule; added a merge_group
  branch that diffs against `merge_group.base_sha` via a new shared
  `fetch_changed_files_compare()` helper (also now used by the
  existing push path, no behavior change there).

Two required checks are deliberately left without merge_group support
and excluded from the new ruleset's required_status_checks, staying
required only via the existing classic config (i.e. still gate a PR
before a committer can add it to the queue, just don't re-run once
it's in one):

- lint-check: validates the PR's own title, which doesn't mean
  anything once re-run against a merge-group ref.
- dependency-review: actions/dependency-review-action has a confirmed,
  currently-unfixed bug on merge_group events (destructures
  github.event.pull_request, which doesn't exist there, and crashes --
  see actions/dependency-review-action#843).

Uses the raw ruleset payload syntax rather than the nicer `merge_queue`
convenience key, since that key is still pending upstream in
apache/infrastructure-asfyaml#119 (not yet merged/deployed as of this
writing) -- .asf.yaml can move to the convenience syntax once that
lands.

- `pytest tests/unit_tests/scripts/change_detector_test.py` -- 13
  passed (8 existing + 5 new: compare-helper delegation, push still
  delegates to it, merge_group happy path, merge_group fails closed
  without MERGE_GROUP_BASE_SHA).
- `ruff check` / `ruff format --check` on the two touched Python files
  -- clean.
- `zizmor` (the same GHA security linter this repo's `validate-all-ghas`
  check runs) against every touched workflow/action file -- no findings.
- `python3 -c "import yaml; yaml.safe_load(...)"` on .asf.yaml and
  every touched workflow file -- all parse.
- Parsed .asf.yaml back with PyYAML to confirm `rulesets` landed as a
  sibling of `protected_branches`, not nested inside it, and printed
  the parsed ruleset structure to confirm the exact shape GitHub's
  Rulesets API expects.
- Could not run pre-commit itself end-to-end -- its git-diffing is
  broken in this environment on an unrelated host xcrun/libxcrun
  architecture mismatch (not something this commit introduces); the
  checks above cover what pre-commit would have run for these file
  types (ruff, YAML validity, zizmor).
- Not yet verified against a live merge-group run (only checkable once
  this actually merges and a real queue entry exercises it).

- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
rusackas added a commit to apache/superset that referenced this pull request Oct 20, 2026
Adds a `github.rulesets` entry to .asf.yaml turning on GitHub's merge
queue for master, alongside the existing classic `protected_branches`
config (the two mechanisms coexist; classic protection still gates
PR-entry-into-queue readiness, the new ruleset adds the merge_queue
rule and its own required_status_checks that must pass against the
queue's synthetic merge-group ref before a batch actually merges).

Wires `merge_group:` support into every workflow that produces one of
those required checks, since GitHub does not run a workflow against a
merge-group ref unless it explicitly listens for that event -- without
this, every queued PR would time out waiting for statuses that never
get reported:

- enforce-single-migration-head.yml: the file-list-based skip
  optimization can't work for merge_group (no pull_request context to
  list files from), so it now always runs the real check there,
  matching the file's own existing fail-closed philosophy -- this is
  also exactly the scenario the check exists for (two migration heads
  that each looked fine alone, combined by the queue).
- pre-commit.yml: the changed-files diff base for merge_group is read
  from the event's own explicit `merge_group.base_sha` rather than
  assuming its commit has the same two-parent shape pull_request's
  synthetic merge commit does.
- scripts/change_detector.py (used by superset-frontend.yml,
  superset-e2e.yml, and all three python test workflows): the change
  detector's event-type dispatch previously raised on anything but
  pull_request/push/workflow_dispatch/schedule; added a merge_group
  branch that diffs against `merge_group.base_sha` via a new shared
  `fetch_changed_files_compare()` helper (also now used by the
  existing push path, no behavior change there).

Two required checks are deliberately left without merge_group support
and excluded from the new ruleset's required_status_checks, staying
required only via the existing classic config (i.e. still gate a PR
before a committer can add it to the queue, just don't re-run once
it's in one):

- lint-check: validates the PR's own title, which doesn't mean
  anything once re-run against a merge-group ref.
- dependency-review: actions/dependency-review-action has a confirmed,
  currently-unfixed bug on merge_group events (destructures
  github.event.pull_request, which doesn't exist there, and crashes --
  see actions/dependency-review-action#843).

Uses the raw ruleset payload syntax rather than the nicer `merge_queue`
convenience key, since that key is still pending upstream in
apache/infrastructure-asfyaml#119 (not yet merged/deployed as of this
writing) -- .asf.yaml can move to the convenience syntax once that
lands.

- `pytest tests/unit_tests/scripts/change_detector_test.py` -- 13
  passed (8 existing + 5 new: compare-helper delegation, push still
  delegates to it, merge_group happy path, merge_group fails closed
  without MERGE_GROUP_BASE_SHA).
- `ruff check` / `ruff format --check` on the two touched Python files
  -- clean.
- `zizmor` (the same GHA security linter this repo's `validate-all-ghas`
  check runs) against every touched workflow/action file -- no findings.
- `python3 -c "import yaml; yaml.safe_load(...)"` on .asf.yaml and
  every touched workflow file -- all parse.
- Parsed .asf.yaml back with PyYAML to confirm `rulesets` landed as a
  sibling of `protected_branches`, not nested inside it, and printed
  the parsed ruleset structure to confirm the exact shape GitHub's
  Rulesets API expects.
- Could not run pre-commit itself end-to-end -- its git-diffing is
  broken in this environment on an unrelated host xcrun/libxcrun
  architecture mismatch (not something this commit introduces); the
  checks above cover what pre-commit would have run for these file
  types (ruff, YAML validity, zizmor).
- Not yet verified against a live merge-group run (only checkable once
  this actually merges and a real queue entry exercises it).

- [ ] Has associated issue:
- [ ] Required feature flags:
- [ ] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API

Co-Authored-By: Evan Rusackas <evan@preset.io>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

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.

3 participants