feat(rust): port stack list + stack open to native Rust#1524
Draft
Conversation
The Rust binary now serves ``mergify stack list [--json]
[--verbose]`` and ``mergify stack open [<commit>]`` natively.
The Python implementations
(``mergify_cli/stack/list.py``,
``mergify_cli/stack/list_schema.py``,
``mergify_cli/stack/open.py``, the click registrations, and
``test_{list,open}.py``) are removed.
New shared infrastructure that the remaining slices
(``stack push``) will reuse:
- ``mergify_stack::changes::classify`` — full per-commit
classifier that buckets each local commit as
``Create`` / ``Update`` / ``SkipMerged`` / ``SkipUpToDate``,
the same shape Python's ``get_changes`` returns. Also
surfaces orphan PRs (open remote changes that don't match
any local commit). The merged-vs-remaining ``sync_status``
module stays for ``stack sync`` since sync only needs the
bucket; the full classifier here is what ``list``, ``open``,
and ``push`` need.
- ``StackContext`` + ``resolve_stack_context`` in the binary
— bundles token / GitHub server / repo slug / author /
branch prefix / trunk resolution that every API-backed stack
subcommand runs. ``checkout`` and ``sync`` will pick this up
in a follow-up cleanup; for now they keep their inline
copies.
``mergify stack list``:
1. Runs the shared stack-context preamble.
2. Walks the local stack via ``local_commits::read``, fetches
the matching remote PRs via ``remote_changes::get_remote_changes``,
classifies via ``changes::classify``.
3. For each entry, computes the display status
(``open`` / ``draft`` / ``merged`` / ``no_pr``) from the
classifier's action plus the PR's ``merged_at`` / ``draft``
fields.
4. Optionally fans out per-PR ``/check-runs`` and ``/reviews``
fetches and folds them into the entry's ``ci_*`` / ``review_*``
fields. Sequential (not concurrent) — GitHub's secondary
rate limit on the same endpoint pool starts firing around
~80 concurrent calls, and a typical stack is well under
that. ``stack open`` passes ``include_status=false`` to
skip this.
5. Renders either JSON (``serde_json::to_string_pretty`` of
``StackListOutput``, byte-compatible with the pre-port
``--json`` output) or a plain-text table.
``mergify stack open``:
1. Runs ``stack::list`` with ``include_status=false``.
2. ``None`` commit → leaf entry (the Python interactive picker
defaulted there too; we leave the picker out of the port for
now).
3. Explicit commit → ``git rev-parse --verify`` then look up
the matching ``StackListEntry``.
4. Hand the ``html_url`` to the OS opener: ``open`` (macOS),
``xdg-open`` (other Unix), ``cmd /C start ""`` (Windows).
5. PR-less commits surface ``StackNotFound`` with a hint to
run ``stack push`` first.
Coverage: 7 ``changes::tests`` for the classifier (create /
skip-merged / amended-after-merge / skip-up-to-date / update /
orphan / closed-unmatched), 6 ``commands::list::tests`` for
the CI / review status reducers (passing / failing-over-pending
/ pending / approved / changes-requested / pending-from-comments).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Change-Id: I0a12ccb23061dceba00b94cbddf93df388452657
This was referenced Jun 3, 2026
Member
Author
|
This pull request is part of a Mergify stack:
|
This was referenced Jun 3, 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
🔴 🤖 Continuous IntegrationWaiting for
This rule is failing.
🔴 👀 Review RequirementsWaiting for
This rule is failing.
🟢 Enforce conventional commitWonderful, this rule succeeded.Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
🟢 🔎 ReviewsWonderful, this rule succeeded.
🟢 📕 PR descriptionWonderful, this rule succeeded.
|
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.
The Rust binary now serves
mergify stack list [--json] [--verbose]andmergify stack open [<commit>]natively.The Python implementations
(
mergify_cli/stack/list.py,mergify_cli/stack/list_schema.py,mergify_cli/stack/open.py, the click registrations, andtest_{list,open}.py) are removed.New shared infrastructure that the remaining slices
(
stack push) will reuse:mergify_stack::changes::classify— full per-commitclassifier that buckets each local commit as
Create/Update/SkipMerged/SkipUpToDate,the same shape Python's
get_changesreturns. Alsosurfaces orphan PRs (open remote changes that don't match
any local commit). The merged-vs-remaining
sync_statusmodule stays for
stack syncsince sync only needs thebucket; the full classifier here is what
list,open,and
pushneed.StackContext+resolve_stack_contextin the binary— bundles token / GitHub server / repo slug / author /
branch prefix / trunk resolution that every API-backed stack
subcommand runs.
checkoutandsyncwill pick this upin a follow-up cleanup; for now they keep their inline
copies.
mergify stack list:local_commits::read, fetchesthe matching remote PRs via
remote_changes::get_remote_changes,classifies via
changes::classify.(
open/draft/merged/no_pr) from theclassifier's action plus the PR's
merged_at/draftfields.
/check-runsand/reviewsfetches and folds them into the entry's
ci_*/review_*fields. Sequential (not concurrent) — GitHub's secondary
rate limit on the same endpoint pool starts firing around
~80 concurrent calls, and a typical stack is well under
that.
stack openpassesinclude_status=falsetoskip this.
serde_json::to_string_prettyofStackListOutput, byte-compatible with the pre-port--jsonoutput) or a plain-text table.mergify stack open:stack::listwithinclude_status=false.Nonecommit → leaf entry (the Python interactive pickerdefaulted there too; we leave the picker out of the port for
now).
git rev-parse --verifythen look upthe matching
StackListEntry.html_urlto the OS opener:open(macOS),xdg-open(other Unix),cmd /C start ""(Windows).StackNotFoundwith a hint torun
stack pushfirst.Coverage: 7
changes::testsfor the classifier (create /skip-merged / amended-after-merge / skip-up-to-date / update /
orphan / closed-unmatched), 6
commands::list::testsforthe CI / review status reducers (passing / failing-over-pending
/ pending / approved / changes-requested / pending-from-comments).
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com
Depends-On: #1523