fix(ci): auto-sync opens a PR + uses merge queue, not direct push - #2234
Merged
Conversation
HongmingWang-Rabbit
requested a review
from hongmingwang-moleculeai
as a code owner
April 28, 2026 22:58
The molecule-core/staging branch is protected by ruleset 15500102
(name: staging-merge-queue) which blocks ALL direct pushes — no
bypass even for org admins or the GitHub Actions integration. The
prior version of this workflow attempted `git push origin staging`
and was rejected with GH013:
! [remote rejected] staging -> staging
(push declined due to repository rule violations)
- Changes must be made through a pull request.
- Changes must be made through the merge queue
This was a real architectural mismatch: auto-sync was bypassing
the same gates everyone else goes through to land on staging,
which is exactly what the ruleset is designed to prevent.
The fix matches the org convention: the workflow now opens a PR
(base=staging, head=auto-sync/main-<sha>) and enables auto-merge.
The merge queue picks it up, runs required gates against the
merged result, and lands it. Same path human PRs take through
staging — no special-snowflake bypass.
Trade-off acknowledged
- Slight PR churn: every main push that needs sync opens a tracked
PR. With concurrency: cancel-in-progress: false (existing) and
the merge queue's serial processing, this is bounded — PRs land
in order, no thundering herd.
- The previous direct-push approach worked on
molecule-controlplane (which has no merge_queue ruleset on
staging). That version of the workflow was correct for that
repo's protection model. Per-repo divergence is acceptable; the
invariant ("staging ⊇ main") is what matters, not how it's
enforced.
Loop safety preserved
GITHUB_TOKEN-authored merges (including the merge queue's land
of this PR) do NOT trigger downstream workflow runs. So the merge
to staging from this PR doesn't fire auto-promote-staging — same
as the direct-push version.
Idempotency
The branch name is derived from main's short sha
(`auto-sync/main-<sha>`) so workflow restarts on the same main
push reuse the existing branch + PR rather than opening duplicates.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
HongmingWang-Rabbit
force-pushed
the
fix/auto-sync-pr-based
branch
from
April 28, 2026 22:59
1a0a40c to
cf258b3
Compare
This was referenced Apr 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The previous auto-sync workflow tried direct `git push origin staging` and was rejected by ruleset 15500102 (`staging-merge-queue`) on every real run. Switches to a PR-based flow that goes through the merge queue, like every other change to staging.
Why
molecule-core/staging is protected by a `merge_queue` ruleset that blocks ALL direct pushes — no bypass for org admins, no bypass for the GitHub Actions integration. The error message included:
```
```
This is by design: human PRs go through review + queue + gates before reaching staging. Auto-sync was carving an exception to that path — exactly what the ruleset prevents. The fix removes the exception.
What changes
Workflow now:
Same path human PRs take. No special-snowflake bypass.
Trade-offs
Slight PR churn. Every main push that needs sync opens a tracked PR. Bounded by concurrency group + merge queue's serial processing. PRs land in order, no thundering herd.
Per-repo divergence. molecule-controlplane uses the simpler direct-push version (its staging has no merge-queue ruleset). Per-repo workflow divergence is acceptable; the invariant (staging ⊇ main) is what matters, not how it's enforced.
Loop safety preserved
GITHUB_TOKEN-authored merges don't trigger downstream workflows. The merge queue's land of the auto-sync PR does NOT fire auto-promote-staging — same loop-safety property as the direct-push version.
Idempotency
Branch name derives from main's short sha (`auto-sync/main-`), so workflow restarts on the same main push reuse the existing branch + PR rather than opening duplicates.
Test plan
Companion to #2210
PR #2210 added this workflow originally with direct-push semantics. It worked locally but failed every real run on molecule-core. This PR is the architectural correction.
🤖 Generated with Claude Code