Skip to content

feat(rust): port config simulate to native Rust (Phase 1.3b)#1298

Draft
jd wants to merge 1 commit intodevs/jd/worktree-rust-port/add-rust-release-workflow-targeting-github--48adf3e4from
devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0
Draft

feat(rust): port config simulate to native Rust (Phase 1.3b)#1298
jd wants to merge 1 commit intodevs/jd/worktree-rust-port/add-rust-release-workflow-targeting-github--48adf3e4from
devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented Apr 23, 2026

Completes the config pilot. Second native command, flipped in
PORT_STATUS.toml from shimmed to native.

What ports natively

mergify config simulate PULL_REQUEST_URL [-f PATH] [-t TOKEN] [-u URL]:

  1. Parses the PR URL into (owner/repo, number). Invalid URLs
    are rejected by clap's value_parser, which exits 2 (matching
    Python's click.BadParameter).
  2. Resolves the config file (same three-location search as
    config validate — shared helper in paths.rs).
  3. Reads the YAML as a raw string (no parsing — the simulator API
    accepts the text verbatim).
  4. Resolves the bearer token: explicit --tokenMERGIFY_TOKEN
    GITHUB_TOKEN → error. Matches Python's precedence; the
    gh auth token subprocess fallback isn't ported yet.
  5. Resolves the API URL: explicit --api-urlMERGIFY_API_URL
    https://api.mergify.com default.
  6. POSTs {"mergify_yml": <content>} to
    /v1/repos/<repo>/pulls/<number>/simulator via the 1.2b HTTP
    client (auth + retry + typed errors).
  7. Prints the returned title + summary to stdout.

Rich Markdown rendering of summary is deliberately deferred —
we print raw Markdown today. Human output drift is allowed by the
compat contract; machine-readable paths aren't affected because
config simulate has no --json flag in Python either.

Dispatch

mergify-cli/src/main.rs now carries two clap subcommands
(validate + simulate). The dispatch logic got a light
reshape: on clap parse failure we distinguish "obvious native
intent" (argv contains config + one of validate/simulate)
from "unrecognized command, fall through". Native-intent parse
errors surface clap's formatted error and exit 2; anything else
falls through to the Python shim so unported commands keep working.

Refactor

The config-path resolver moved from validate.rs into a shared
paths.rs module so both commands share a single source of
truth for the [".mergify.yml", ".mergify/config.yml", ".github/mergify.yml"] search list.

Tests

24 tests in mergify-config (up from 11 in Phase 1.3):

  • 3 for the shared path resolver (moved out of validate.rs)
  • 6 for PR URL parsing (happy path + 5 rejection cases)
  • 4 for token resolution (explicit, env fallback, error)
  • 2 for API URL resolution
  • 1 end-to-end wiremock test: POST + JSON body + auth header +
    response rendering

Covered by the port-inventory guard: PORT_STATUS.toml flips
config simulate from shimmed to native.

Binary size: 8.0 MB → 8.3 MB (small bump from simulate.rs).

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Depends-On: #1297

@jd
Copy link
Copy Markdown
Member Author

jd commented Apr 23, 2026

This pull request is part of a Mergify stack:

# Pull Request Link
1 ci(renovate): group cargo / github-actions updates and enable lockFileMaintenance #1307
2 feat(rust): add mergify-core::http with retry + typed errors (Phase 1.2b) #1281
3 feat(rust): port config validate to native Rust (Phase 1.3) #1282
4 test: add port-inventory guard to catch un-ported Python commands #1296
5 ci: add Rust release workflow targeting GitHub Release assets #1297
6 feat(rust): port config simulate to native Rust (Phase 1.3b) #1298 👈
7 feat(rust): port ci scopes-send to native Rust (Phase 1.4) #1300
8 feat(rust): port queue pause and unpause to native Rust (Phase 1.5) #1301
9 feat(rust): port ci git-refs and ci queue-info to native Rust (Phase 1.6) #1302

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 23, 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 April 23, 2026 14:14
@jd jd force-pushed the devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0 branch from 2a502cd to e4397c6 Compare April 23, 2026 19:02
@jd
Copy link
Copy Markdown
Member Author

jd commented Apr 23, 2026

Revision history

# Type Changes Reason Date
1 initial 2a502cd 2026-04-23 19:02 UTC
2 rebase 2a502cd → e4397c6 2026-04-23 19:02 UTC
3 rebase e4397c6 → 6dee3f1 2026-04-24 13:41 UTC
4 rebase cc09d55 → f5f004a 2026-04-27 07:03 UTC
5 rebase f5f004a → d7398e1 2026-04-28 06:48 UTC

@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 23, 2026 19:03 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0 branch from e4397c6 to 6dee3f1 Compare April 24, 2026 13:41
@jd jd force-pushed the devs/jd/worktree-rust-port/add-rust-release-workflow-targeting-github--48adf3e4 branch from cb257f5 to 44fc353 Compare April 24, 2026 13:41
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 24, 2026 13:41 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0 branch from 6dee3f1 to cc09d55 Compare April 27, 2026 06:18
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 27, 2026 06:18 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0 branch from cc09d55 to f5f004a Compare April 27, 2026 07:03
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 27, 2026 07:03 Failure
Completes the config pilot. Second native command, flipped in
PORT_STATUS.toml from ``shimmed`` to ``native``.

## What ports natively

``mergify config simulate PULL_REQUEST_URL [-f PATH] [-t TOKEN] [-u URL]``:

1. Parses the PR URL into ``(owner/repo, number)``. Invalid URLs
   are rejected by clap's ``value_parser``, which exits 2 (matching
   Python's ``click.BadParameter``).
2. Resolves the config file (same three-location search as
   ``config validate`` — shared helper in ``paths.rs``).
3. Reads the YAML as a raw string (no parsing — the simulator API
   accepts the text verbatim).
4. Resolves the bearer token: explicit ``--token`` → ``MERGIFY_TOKEN``
   → ``GITHUB_TOKEN`` → error. Matches Python's precedence; the
   ``gh auth token`` subprocess fallback isn't ported yet.
5. Resolves the API URL: explicit ``--api-url`` → ``MERGIFY_API_URL``
   → ``https://api.mergify.com`` default.
6. POSTs ``{"mergify_yml": <content>}`` to
   ``/v1/repos/<repo>/pulls/<number>/simulator`` via the 1.2b HTTP
   client (auth + retry + typed errors).
7. Prints the returned title + summary to stdout.

Rich Markdown rendering of ``summary`` is deliberately deferred —
we print raw Markdown today. Human output drift is allowed by the
compat contract; machine-readable paths aren't affected because
``config simulate`` has no ``--json`` flag in Python either.

## Dispatch

``mergify-cli/src/main.rs`` now carries two clap subcommands
(``validate`` + ``simulate``). The dispatch logic got a light
reshape: on clap parse failure we distinguish "obvious native
intent" (argv contains ``config`` + one of ``validate``/``simulate``)
from "unrecognized command, fall through". Native-intent parse
errors surface clap's formatted error and exit 2; anything else
falls through to the Python shim so unported commands keep working.

## Refactor

The config-path resolver moved from ``validate.rs`` into a shared
``paths.rs`` module so both commands share a single source of
truth for the ``[".mergify.yml", ".mergify/config.yml",
".github/mergify.yml"]`` search list.

## Tests

24 tests in ``mergify-config`` (up from 11 in Phase 1.3):

- 3 for the shared path resolver (moved out of ``validate.rs``)
- 6 for PR URL parsing (happy path + 5 rejection cases)
- 4 for token resolution (explicit, env fallback, error)
- 2 for API URL resolution
- 1 end-to-end wiremock test: POST + JSON body + auth header +
  response rendering

Covered by the port-inventory guard: ``PORT_STATUS.toml`` flips
``config simulate`` from ``shimmed`` to ``native``.

Binary size: 8.0 MB → 8.3 MB (small bump from simulate.rs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Change-Id: If9194bb015c12c14cf71a9e831c4e1d67391793e
@jd jd force-pushed the devs/jd/worktree-rust-port/port-config-simulate-native-rust-phase-1-3b--f9194bb0 branch from f5f004a to d7398e1 Compare April 28, 2026 06:48
@jd jd force-pushed the devs/jd/worktree-rust-port/add-rust-release-workflow-targeting-github--48adf3e4 branch from 9e9ef12 to 6def985 Compare April 28, 2026 06:48
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 28, 2026 06:49 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