Skip to content

feat(rust): port stack checkout to native Rust#1522

Draft
jd wants to merge 1 commit into
devs/jd/feat/rust-stack-new/port-stack-squash-native-rust--380f216cfrom
devs/jd/feat/rust-stack-new/port-stack-checkout-native-rust--71e74cae
Draft

feat(rust): port stack checkout to native Rust#1522
jd wants to merge 1 commit into
devs/jd/feat/rust-stack-new/port-stack-squash-native-rust--380f216cfrom
devs/jd/feat/rust-stack-new/port-stack-checkout-native-rust--71e74cae

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented Jun 3, 2026

The Rust binary now serves mergify stack checkout <NAME>
natively. mergify_cli/stack/checkout.py,
mergify_cli/tests/stack/test_checkout.py, and the click
registration are removed in the same PR.

First GitHub-API-backed stack subcommand to land natively. The
slice introduces a shared mergify_stack::stack_context module
that resolves the per-command preamble — repository owner/repo,
GitHub API server URL, default branch prefix — that sync,
list, open, and push will all reuse when their ports
follow.

mergify_stack::stack_context:

  • parse_slug — owner/repo extraction handling both
    https://github.com/o/r.git and git@github.com:o/r.git
    shapes, port of utils.get_slug.
  • resolve_repo — explicit --repository OWNER/REPO
    takes precedence; otherwise we parse
    git config remote.<remote>.url.
  • resolve_github_server — reads
    mergify-cli.github-server git config, falls back to
    https://api.github.com/, mirrors Python's https-coercion +
    /api/v3 suffix for GitHub Enterprise.
  • resolve_default_branch_prefix — reads
    mergify-cli.stack-branch-prefix, falls back to
    stack/<author>.

mergify_stack::commands::checkout:

  1. Normalises the NAME argument — strip any trailing
    /Ixxxx… Change-Id suffix (via the new
    change_id::strip_branch_suffix helper) and any leading
    <branch_prefix>/ so users can paste a leaf branch ref
    verbatim.
  2. Searches GitHub for the stack's PRs via the existing
    mergify_stack::remote_changes::get_remote_changes.
  3. Builds the open-PR chain from root to leaf — root is the PR
    whose base.ref doesn't start with the stack branch
    prefix; we walk up via head.refbase.ref linking.
    Two roots surface as InvalidState, matching Python.
  4. --dry-run short-circuits with the printed chain.
    Otherwise git fetch <remote> <leaf-head>,
    git checkout -b <local> <remote>/<leaf-head>,
    git branch --set-upstream-to=<remote>/<root-base>.

Binary handler resolves the trunk via --trunk REMOTE/BRANCH
or the existing mergify_stack::trunk::get_trunk fallback,
the token via mergify_core::auth::resolve_token, and the
author via either --author or GET /user against the
resolved client.

Coverage in crates/mergify-stack/src/commands/checkout.rs
(7 tests): the pure chain builder (root-to-leaf, closed-PR
filter, two-root detection, empty case) plus three end-to-end
run tests against wiremock — no-stacked-prs, dry-run returns
chain without touching git, name normalisation strips both the
Change-Id suffix and the branch prefix.

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

Depends-On: #1521

@jd
Copy link
Copy Markdown
Member Author

jd commented Jun 3, 2026

This pull request is part of a Mergify stack:

# Pull Request Link
1 feat(rust): port stack note to native Rust #1515
2 feat(rust): port stack edit + add rebase-todo machinery #1516
3 feat(rust): port stack drop to native Rust #1517
4 feat(rust): port stack fixup to native Rust #1518
5 feat(rust): port stack reword to native Rust #1519
6 feat(rust): port stack reorder + stack move to native Rust #1520
7 feat(rust): port stack squash to native Rust #1521
8 feat(rust): port stack checkout to native Rust #1522 👈
9 feat(rust): port stack sync to native Rust #1523
10 feat(rust): port stack list + stack open to native Rust #1524

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Jun 3, 2026

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🔴 ⛓️ Depends-On Requirements

Waiting for

This rule is failing.

Requirement based on the presence of Depends-On in the body of the pull request

🔴 👀 Review Requirements

Waiting for

  • #approved-reviews-by>=2
This rule is failing.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
This rule is failing.
  • #review-requested = 0
  • #changes-requested-reviews-by = 0
  • #review-threads-unresolved = 0

🟢 🤖 Continuous Integration

Wonderful, this rule succeeded.
  • all of:
    • check-success=ci-gate

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?:

🟢 📕 PR description

Wonderful, this rule succeeded.
  • body ~= (?ms:.{48,})

@mergify mergify Bot requested a review from a team June 3, 2026 20:02
The Rust binary now serves ``mergify stack checkout <NAME>``
natively. ``mergify_cli/stack/checkout.py``,
``mergify_cli/tests/stack/test_checkout.py``, and the click
registration are removed in the same PR.

First GitHub-API-backed stack subcommand to land natively. The
slice introduces a shared ``mergify_stack::stack_context`` module
that resolves the per-command preamble — repository owner/repo,
GitHub API server URL, default branch prefix — that ``sync``,
``list``, ``open``, and ``push`` will all reuse when their ports
follow.

``mergify_stack::stack_context``:
- ``parse_slug`` — owner/repo extraction handling both
  ``https://github.com/o/r.git`` and ``git@github.com:o/r.git``
  shapes, port of ``utils.get_slug``.
- ``resolve_repo`` — explicit ``--repository OWNER/REPO``
  takes precedence; otherwise we parse
  ``git config remote.<remote>.url``.
- ``resolve_github_server`` — reads
  ``mergify-cli.github-server`` git config, falls back to
  ``https://api.github.com/``, mirrors Python's https-coercion +
  ``/api/v3`` suffix for GitHub Enterprise.
- ``resolve_default_branch_prefix`` — reads
  ``mergify-cli.stack-branch-prefix``, falls back to
  ``stack/<author>``.

``mergify_stack::commands::checkout``:

1. Normalises the ``NAME`` argument — strip any trailing
   ``/Ixxxx…`` Change-Id suffix (via the new
   ``change_id::strip_branch_suffix`` helper) and any leading
   ``<branch_prefix>/`` so users can paste a leaf branch ref
   verbatim.
2. Searches GitHub for the stack's PRs via the existing
   ``mergify_stack::remote_changes::get_remote_changes``.
3. Builds the open-PR chain from root to leaf — root is the PR
   whose ``base.ref`` doesn't start with the stack branch
   prefix; we walk up via ``head.ref`` → ``base.ref`` linking.
   Two roots surface as ``InvalidState``, matching Python.
4. ``--dry-run`` short-circuits with the printed chain.
   Otherwise ``git fetch <remote> <leaf-head>``,
   ``git checkout -b <local> <remote>/<leaf-head>``,
   ``git branch --set-upstream-to=<remote>/<root-base>``.

Binary handler resolves the trunk via ``--trunk REMOTE/BRANCH``
or the existing ``mergify_stack::trunk::get_trunk`` fallback,
the token via ``mergify_core::auth::resolve_token``, and the
author via either ``--author`` or ``GET /user`` against the
resolved client.

Coverage in ``crates/mergify-stack/src/commands/checkout.rs``
(7 tests): the pure chain builder (root-to-leaf, closed-PR
filter, two-root detection, empty case) plus three end-to-end
``run`` tests against wiremock — no-stacked-prs, dry-run returns
chain without touching git, name normalisation strips both the
Change-Id suffix and the branch prefix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Change-Id: I71e74cae43846d9708bef9c57d32ba81b8499edc
@jd jd force-pushed the devs/jd/feat/rust-stack-new/port-stack-squash-native-rust--380f216c branch from 9342e5c to f86d325 Compare June 3, 2026 21:01
@jd jd force-pushed the devs/jd/feat/rust-stack-new/port-stack-checkout-native-rust--71e74cae branch from 0da0845 to b09a7f8 Compare June 3, 2026 21:01
@jd
Copy link
Copy Markdown
Member Author

jd commented Jun 3, 2026

Revision history

# Type Changes Reason Date
1 initial 0da0845 2026-06-03 21:01 UTC
2 rebase 0da0845 → b09a7f8 (rebase only) 2026-06-03 21:01 UTC

@jd jd temporarily deployed to func-tests-live June 3, 2026 21:01 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live June 3, 2026 21:01 — with GitHub Actions Inactive
@mergify mergify Bot had a problem deploying to Mergify Merge Protections June 3, 2026 21:01 Failure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant