Skip to content

feat(rust): add mergify_core::auth with gh and git-config fallbacks#1364

Merged
mergify[bot] merged 2 commits intomainfrom
devs/jd/worktree-rust-port/add-mergify-core-auth-gh-git-config-fallbacks--3ae3542b
May 6, 2026
Merged

feat(rust): add mergify_core::auth with gh and git-config fallbacks#1364
mergify[bot] merged 2 commits intomainfrom
devs/jd/worktree-rust-port/add-mergify-core-auth-gh-git-config-fallbacks--3ae3542b

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented May 5, 2026

Centralizes the --token / --api-url / --repository resolvers
into one module so every ported command (config simulate,
ci scopes-send, the queue commands that follow in this stack)
shares the same fallback behavior:

  • resolve_token: explicit → MERGIFY_TOKENGITHUB_TOKEN
    gh auth token (subprocess; missing-binary or non-zero-exit
    is treated as "no token from gh", same as Python's
    CommandError catch in utils.get_default_token).

  • resolve_repository: explicit → GITHUB_REPOSITORY
    git config --get remote.origin.url parsed via parse_slug
    (handles HTTPS and SSH shapes, strips .git and trailing
    slashes).

  • resolve_api_url: explicit → MERGIFY_API_URL
    default https://api.mergify.com.

The gh and git fallbacks are best-effort: missing binaries
or non-zero exits propagate as "fall through to the next source"
rather than surfacing errors. Mirrors the Python implementation.

mergify-config::simulate and mergify-ci::scopes_send are
refactored in this same commit to use the new module — their
local copies of the resolvers (which were missing the gh / git
fallbacks) are removed. The duplicate tests that lived in those
modules are dropped; the env-precedence and slug-parsing coverage
now lives once in mergify_core::auth::tests.

13 new tests in mergify_core::auth::tests: env-var precedence
for token/api-url/repository, default API URL, error message
mentions gh client, slug parsing for HTTPS / SSH / dot-git /
trailing-slash / empty-owner / path-without-repo. The
subprocess-fallback paths themselves aren't unit-tested (they
shell out to real binaries); the
resolve_token_error_message_mentions_gh test exercises the
"PATH points to a directory with no gh" case to confirm the
fallback degrades cleanly.

The queue ports later in the stack consume this module from the
start — there's no transition period where they ship with a
private auth resolver.

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

Depends-On: #1357

@jd
Copy link
Copy Markdown
Member Author

jd commented May 5, 2026

This pull request is part of a Mergify stack:

# Pull Request Link
1 docs(port): add port review checklist for HTTP/test/UX parity pitfalls #1357
2 feat(rust): add mergify_core::auth with gh and git-config fallbacks #1364 👈
3 feat(rust): port queue pause and unpause to native Rust #1352
4 feat(rust): port ci git-refs and ci queue-info to native Rust #1353
5 feat(rust): port queue status to native Rust #1359
6 test: derive native queue commands from the binary, not a hardcoded list #1366

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 5, 2026

Merge Protections

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

🟢 ⛓️ Depends-On Requirements

Wonderful, this rule succeeded.

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

🟢 🤖 Continuous Integration

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

🟢 👀 Review Requirements

Wonderful, this rule succeeded.
  • any of:
    • #approved-reviews-by>=2
    • author = dependabot[bot]
    • author = mergify-ci-bot
    • author = renovate[bot]

🟢 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)(?:\(.+\))?:

🟢 🔎 Reviews

Wonderful, this rule succeeded.
  • #changes-requested-reviews-by = 0
  • #review-requested = 0
  • #review-threads-unresolved = 0

🟢 📕 PR description

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

@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 5, 2026 15:18 Failure
@jd jd marked this pull request as ready for review May 5, 2026 15:21
@mergify mergify Bot requested a review from a team May 5, 2026 15:29
@jd jd force-pushed the devs/jd/worktree-rust-port/add-mergify-core-auth-gh-git-config-fallbacks--3ae3542b branch from f5aaca2 to 98a9a67 Compare May 5, 2026 19:58
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-review-checklist-http-test-ux-parity--1fd9757e branch from 6b1d62e to d8f08a0 Compare May 5, 2026 19:59
@jd
Copy link
Copy Markdown
Member Author

jd commented May 5, 2026

Revision history

# Type Changes Reason Date
1 initial f5aaca2 2026-05-05 19:59 UTC
2 content f5aaca2 → 98a9a67 2026-05-05 19:59 UTC
3 rebase 98a9a67 → 458b512 2026-05-06 10:57 UTC

@mergify mergify Bot had a problem deploying to Mergify Merge Protections May 5, 2026 19:59 Failure
jd and others added 2 commits May 6, 2026 12:56
The 2026.5.5.x release shipped a ``ci scopes-send`` regression
(fixed in #1356): the Rust port deserialized the response body via
``let _: serde_json::Value = client.post(...)`` while the Python
original ignored the body, and the Mergify endpoint returns an
empty body on success. ``Value`` still requires valid JSON, so the
Rust version surfaced ``parse response JSON: error decoding
response body`` to every user once it shipped. Test mocks used
``set_body_json(json!({}))`` instead of an empty body, so the bug
hid through unit tests too.

The fix is structural — split the HTTP client so callers pick
``post`` (parses) vs ``post_no_response`` (drops) up front — but
the bug class is broader than this one command. Capturing the
lessons in AGENTS.md so the next porter (human or assistant) walks
through them before opening a PR.

Three categories of pitfall, all observed during the port so far:

1. **HTTP response handling** — match the Python original. If
   Python ignores the response, Rust must use ``post_no_response``
   etc.; if Python parses, optional/nullable fields must be
   ``Option<T>`` + ``#[serde(default)]``.

2. **Test fixtures** — mirror the real server. ``ResponseTemplate``
   bodies must match what the endpoint actually returns; an empty
   body is not the same as ``json!({})``.

3. **UX parity with click** — char-counted validators use
   ``chars().count()`` (not ``len()``); confirmation prompts go to
   stderr; resolve all required state before prompting.

Audit of existing/in-flight ports against the checklist:

- ``config validate``, ``config simulate`` (main): match
- ``ci scopes-send`` (main): regressed, fix in #1356
- ``queue pause`` / ``unpause`` (#1352): match
- ``ci git-refs`` / ``queue-info`` (#1353): no HTTP, no risk

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Change-Id: I1fd9757e7f0213b0aeecbb6eb52b59e689cdf05a
Centralizes the `--token` / `--api-url` / `--repository` resolvers
into one module so every ported command (config simulate,
ci scopes-send, the queue commands that follow in this stack)
shares the same fallback behavior:

- ``resolve_token``: explicit → ``MERGIFY_TOKEN`` → ``GITHUB_TOKEN``
  → ``gh auth token`` (subprocess; missing-binary or non-zero-exit
  is treated as "no token from gh", same as Python's
  ``CommandError`` catch in ``utils.get_default_token``).

- ``resolve_repository``: explicit → ``GITHUB_REPOSITORY`` →
  ``git config --get remote.origin.url`` parsed via ``parse_slug``
  (handles HTTPS and SSH shapes, strips ``.git`` and trailing
  slashes).

- ``resolve_api_url``: explicit → ``MERGIFY_API_URL`` →
  default ``https://api.mergify.com``.

The ``gh`` and ``git`` fallbacks are best-effort: missing binaries
or non-zero exits propagate as "fall through to the next source"
rather than surfacing errors. Mirrors the Python implementation.

``mergify-config::simulate`` and ``mergify-ci::scopes_send`` are
refactored in this same commit to use the new module — their
local copies of the resolvers (which were missing the gh / git
fallbacks) are removed. The duplicate tests that lived in those
modules are dropped; the env-precedence and slug-parsing coverage
now lives once in ``mergify_core::auth::tests``.

13 new tests in ``mergify_core::auth::tests``: env-var precedence
for token/api-url/repository, default API URL, error message
mentions ``gh client``, slug parsing for HTTPS / SSH / dot-git /
trailing-slash / empty-owner / path-without-repo. The
subprocess-fallback paths themselves aren't unit-tested (they
shell out to real binaries); the
``resolve_token_error_message_mentions_gh`` test exercises the
"PATH points to a directory with no gh" case to confirm the
fallback degrades cleanly.

The queue ports later in the stack consume this module from the
start — there's no transition period where they ship with a
private auth resolver.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Change-Id: I3ae3542b75bf407150b2607f50255ec91e9e9587
@jd jd force-pushed the devs/jd/worktree-rust-port/add-mergify-core-auth-gh-git-config-fallbacks--3ae3542b branch from 98a9a67 to 458b512 Compare May 6, 2026 10:57
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-review-checklist-http-test-ux-parity--1fd9757e branch from d8f08a0 to 2b149f4 Compare May 6, 2026 10:57
@jd jd temporarily deployed to func-tests-live May 6, 2026 10:57 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 6, 2026 10:57 — with GitHub Actions Inactive
@jd jd temporarily deployed to func-tests-live May 6, 2026 10:57 — with GitHub Actions Inactive
@mergify mergify Bot deployed to Mergify Merge Protections May 6, 2026 10:57 Active
@mergify mergify Bot requested a review from a team May 6, 2026 12:08
Base automatically changed from devs/jd/worktree-rust-port/add-port-review-checklist-http-test-ux-parity--1fd9757e to main May 6, 2026 12:23
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented May 6, 2026

Merge Queue Status

This pull request spent 16 minutes 25 seconds in the queue, including 13 minutes 20 seconds running CI.

Required conditions to merge

mergify Bot added a commit that referenced this pull request May 6, 2026
@mergify mergify Bot added the queued label May 6, 2026
@mergify mergify Bot merged commit 878d703 into main May 6, 2026
53 checks passed
@mergify mergify Bot deleted the devs/jd/worktree-rust-port/add-mergify-core-auth-gh-git-config-fallbacks--3ae3542b branch May 6, 2026 12:49
@mergify mergify Bot removed the queued label May 6, 2026
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.

3 participants