feat(rust): port stack push end-to-end + delete Python push.py#1553
Conversation
Member
Author
|
This pull request is part of a Mergify stack:
|
This was referenced Jun 5, 2026
Contributor
Merge ProtectionsYour pull request matches the following merge protections and will not be merged until they are valid. 🔴 ⛓️ Depends-On RequirementsWaiting for
This rule is failing.Requirement based on the presence of
🔴 👀 Review RequirementsWaiting for
This rule is failing.
🔴 🔎 ReviewsWaiting for
This rule is failing.
🟢 🤖 Continuous IntegrationWonderful, this rule succeeded.
🟢 Enforce conventional commitWonderful, this rule succeeded.Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
🟢 📕 PR descriptionWonderful, this rule succeeded.
|
e5c33cc to
d2bd9e8
Compare
0ed6917 to
9767f5b
Compare
Member
Author
Revision history
|
9767f5b to
bcaa5fa
Compare
d2bd9e8 to
291e013
Compare
End-to-end native port of `mergify stack push`: wires every
leaf module, the orchestrator, and the binary dispatch in one
self-consistent change so `mergify stack push` works on the
Rust binary and the Python implementation gets deleted in the
same commit.
New `mergify-stack` modules (each is a faithful port from
`mergify_cli/stack/`):
- `change_type` — patch-id-based rebase-vs-content
classification + `refs/pull/<n>/head` fetch helper.
- `stack_comment` — the "this PR is part of a stack" sticky
comment renderer + header recogniser. JSON marker stays
byte-for-byte compatible with historic comments.
- `replay` — `git merge-tree` + `git diff-tree` + the HTTP
upload (`POST /git/trees` + `POST /git/commits`) that
materialise the rebase-aware revision-history compare URL.
- `revision_history` — the "Revision history" sticky comment
with parse + append + render round-tripping byte-for-byte
against the Python implementation.
- `approvals` — the rebase/no-rebase decision: skip the
rebase when PRs are already approved (so reviews aren't
dismissed) unless the bottom of the stack has a real merge
conflict with trunk.
- `notes_push` — `git fetch`/`git push` plumbing for
`refs/notes/mergify/stack` + the per-PR refspecs that
`stack push` lands atomically with `--force-with-lease`.
- `rebase_log` — pure formatters for the three rebase
narration log lines.
- `push_helpers` — `format_pull_description` (strip
Change-Id + stale Depends-On, append fresh Depends-On) +
`build_change_tasks` (the per-PR dependency graph).
- `pr_upsert` — per-PR Create (POST /pulls) and Update
(PATCH /pulls/<n>) + orphan branch teardown.
- `comment_upsert` — per-PR sticky-comment upserters: stack
comment (skip-when-single-PR) + revision history (parse +
append + recover-from-corrupt).
- `plan` — the layer above `classify` that applies the
`--next-only` / `--only-update-existing-pulls` overrides
and resolves `dest_branch` / `base_branch`.
- `changes::Action` extended with `SkipCreate` /
`SkipNextOnly` so the planner can surface
would-be-created PRs without opening any.
- `commands::push` — the end-to-end orchestrator wiring
every leaf above. Runs per-PR upserts sequentially
(typical 2-5 PR stacks make the latency difference
negligible vs. the GitHub round-trip cost, and the
simpler code avoids a `tokio::sync::Notify` graph).
Binary wiring (`crates/mergify-cli/src/main.rs`):
- `NativeCommand::StackPush(StackPushOpts)` variant +
`StackPushCli` clap struct mirroring the Python click
option surface 1:1 (`--skip-rebase`, `--force-rebase`,
`--next-only`, `--dry-run`, `--draft`, `--keep-pull-
request-title-and-body`, `--author`, `--trunk`,
`--branch-prefix`, `--only-update-existing-pulls`,
`--no-revision-history`, `--no-verify`).
- `dispatch_stack` "push" arm routing through to
`commands::push::run`.
- `("stack", "push")` added to `NATIVE_COMMANDS`.
Python deletion:
- `mergify_cli/stack/push.py` (the orchestrator, 1394 LOC).
- `mergify_cli/stack/{sync,approvals,replay,changes}.py` —
helpers only imported by push.py and its tests.
- `mergify_cli/tests/stack/test_{push,replay,approvals}.py`.
- `mergify_cli/stack/cli.py` — the `push` command + the
`stack_push_mod` import. The click group itself stays
so `python -m mergify_cli stack` keeps printing help
until the package is removed wholesale in the follow-up.
Adds `chrono` (with `clock` feature) and `tokio` (with
`time` feature) + `url` to `mergify-stack`'s prod deps to
support the revision-history timestamps, the
mergeable-retry sleep, and the wiremock test base-URL
parse.
End-to-end verified against the Python implementation on
real fixtures (stack-comment + revision-history bodies
match byte-for-byte; planner action overrides match the
Python `get_changes` semantics including the
`--next-only` × `--only-update-existing-pulls` interaction
at idx 0).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Change-Id: I1b2c30509153a19071cf495155a03e9a2e616e87
bcaa5fa to
f74c92d
Compare
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.
End-to-end native port of
mergify stack push: wires everyleaf module, the orchestrator, and the binary dispatch in one
self-consistent change so
mergify stack pushworks on theRust binary and the Python implementation gets deleted in the
same commit.
New
mergify-stackmodules (each is a faithful port frommergify_cli/stack/):change_type— patch-id-based rebase-vs-contentclassification +
refs/pull/<n>/headfetch helper.stack_comment— the "this PR is part of a stack" stickycomment renderer + header recogniser. JSON marker stays
byte-for-byte compatible with historic comments.
replay—git merge-tree+git diff-tree+ the HTTPupload (
POST /git/trees+POST /git/commits) thatmaterialise the rebase-aware revision-history compare URL.
revision_history— the "Revision history" sticky commentwith parse + append + render round-tripping byte-for-byte
against the Python implementation.
approvals— the rebase/no-rebase decision: skip therebase when PRs are already approved (so reviews aren't
dismissed) unless the bottom of the stack has a real merge
conflict with trunk.
notes_push—git fetch/git pushplumbing forrefs/notes/mergify/stack+ the per-PR refspecs thatstack pushlands atomically with--force-with-lease.rebase_log— pure formatters for the three rebasenarration log lines.
push_helpers—format_pull_description(stripChange-Id + stale Depends-On, append fresh Depends-On) +
build_change_tasks(the per-PR dependency graph).pr_upsert— per-PR Create (POST /pulls) and Update(PATCH /pulls/) + orphan branch teardown.
comment_upsert— per-PR sticky-comment upserters: stackcomment (skip-when-single-PR) + revision history (parse +
append + recover-from-corrupt).
plan— the layer aboveclassifythat applies the--next-only/--only-update-existing-pullsoverridesand resolves
dest_branch/base_branch.changes::Actionextended withSkipCreate/SkipNextOnlyso the planner can surfacewould-be-created PRs without opening any.
commands::push— the end-to-end orchestrator wiringevery leaf above. Runs per-PR upserts sequentially
(typical 2-5 PR stacks make the latency difference
negligible vs. the GitHub round-trip cost, and the
simpler code avoids a
tokio::sync::Notifygraph).Binary wiring (
crates/mergify-cli/src/main.rs):NativeCommand::StackPush(StackPushOpts)variant +StackPushCliclap struct mirroring the Python clickoption surface 1:1 (
--skip-rebase,--force-rebase,--next-only,--dry-run,--draft,--keep-pull- request-title-and-body,--author,--trunk,--branch-prefix,--only-update-existing-pulls,--no-revision-history,--no-verify).dispatch_stack"push" arm routing through tocommands::push::run.("stack", "push")added toNATIVE_COMMANDS.Python deletion:
mergify_cli/stack/push.py(the orchestrator, 1394 LOC).mergify_cli/stack/{sync,approvals,replay,changes}.py—helpers only imported by push.py and its tests.
mergify_cli/tests/stack/test_{push,replay,approvals}.py.mergify_cli/stack/cli.py— thepushcommand + thestack_push_modimport. The click group itself staysso
python -m mergify_cli stackkeeps printing helpuntil the package is removed wholesale in the follow-up.
Adds
chrono(withclockfeature) andtokio(withtimefeature) +urltomergify-stack's prod deps tosupport the revision-history timestamps, the
mergeable-retry sleep, and the wiremock test base-URL
parse.
End-to-end verified against the Python implementation on
real fixtures (stack-comment + revision-history bodies
match byte-for-byte; planner action overrides match the
Python
get_changessemantics including the--next-only×--only-update-existing-pullsinteractionat idx 0).
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com
Depends-On: #1527