Skip to content

test: add port-inventory guard to catch un-ported Python commands#1296

Merged
mergify[bot] merged 1 commit intomainfrom
devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672
Apr 29, 2026
Merged

test: add port-inventory guard to catch un-ported Python commands#1296
mergify[bot] merged 1 commit intomainfrom
devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672

Conversation

@jd
Copy link
Copy Markdown
Member

@jd jd commented Apr 23, 2026

During the Rust port, any new click command added to the Python CLI
risks being silently missed if the Rust dispatch isn't updated in
parallel. This adds a CI-enforced inventory at the repo root plus
a pytest that walks the click tree and compares against it.

How it works

PORT_STATUS.toml lists every click subcommand with an explicit
status of either native (handled by Rust's dispatch) or
shimmed (forwarded to Python by the py-shim crate).
mergify_cli/tests/test_port_status.py walks mergify_cli.cli.cli
and fires four assertions:

  • Every discovered click command has an entry.
  • Every entry corresponds to a live click command (no stale rows).
  • Every entry uses a valid status value.
  • No entry carries extra keys (catches typos like stats).

Forgetting to update the file when adding a new Python command
becomes a CI failure at test-time rather than a "why is this
missing from the binary?" bug report months later.

Current baseline

All 30 click subcommands are listed. Only config validate is
native today (from Phase 1.3 in the same stack). The remaining
29 are shimmed — each subsequent port PR flips its entry from
shimmed to native in the same commit that adds the Rust
dispatch, keeping the file and the code in lockstep.

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

@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 test: add port-inventory guard to catch un-ported Python commands #1296 👈
2 ci: add Rust release workflow targeting GitHub Release assets #1297
3 feat(rust): port config simulate to native Rust (Phase 1.3b) #1298
4 feat(rust): port ci scopes-send to native Rust (Phase 1.4) #1300
5 feat(rust): port queue pause and unpause to native Rust (Phase 1.5) #1301
6 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.

🟢 🤖 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,})

@jd
Copy link
Copy Markdown
Member Author

jd commented Apr 23, 2026

Revision history

# Type Changes Reason Date
1 initial b887a4a 2026-04-23 19:02 UTC
2 rebase b887a4a → fddda52 2026-04-23 19:02 UTC
3 rebase fddda52 → 3390a13 2026-04-24 13:41 UTC
4 rebase 6c36176 → 93047fd 2026-04-27 07:03 UTC
5 rebase 93047fd → e525b00 2026-04-28 06:48 UTC
6 rebase e525b00 → cc28fea 2026-04-28 14:09 UTC
7 rebase cc28fea → 2521caa 2026-04-29 07:02 UTC
8 content 2521caa → 631557e 2026-04-29 09:06 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-validate-native-rust-phase-1-3--52ffe9eb branch from 1bccca9 to db76eee Compare April 24, 2026 13:41
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from fddda52 to 3390a13 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/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from 3390a13 to 6c36176 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/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from 6c36176 to 93047fd Compare April 27, 2026 07:03
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 27, 2026 07:03 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from 93047fd to e525b00 Compare April 28, 2026 06:48
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 28, 2026 06:49 Failure
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from e525b00 to cc28fea Compare April 28, 2026 14:09
@jd jd force-pushed the devs/jd/worktree-rust-port/port-config-validate-native-rust-phase-1-3--52ffe9eb branch from 6470fc5 to a286dbf Compare April 28, 2026 14:09
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 28, 2026 14:13 Failure
@jd jd marked this pull request as ready for review April 28, 2026 14:39
Base automatically changed from devs/jd/worktree-rust-port/port-config-validate-native-rust-phase-1-3--52ffe9eb to main April 28, 2026 15:02
Copilot AI review requested due to automatic review settings April 29, 2026 07:02
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from cc28fea to 2521caa Compare April 29, 2026 07:02
@mergify mergify Bot had a problem deploying to Mergify Merge Protections April 29, 2026 07:04 Failure
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a CI guardrail to keep the Python Click CLI command surface area in sync with the ongoing Rust port by introducing a repository-wide command inventory and a pytest that compares discovered Click commands against that inventory.

Changes:

  • Add PORT_STATUS.toml at repo root to inventory all Click leaf subcommands with status = "native" / status = "shimmed".
  • Add mergify_cli/tests/test_port_status.py to walk the Click command tree and assert the inventory is complete, non-stale, and well-formed.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
mergify_cli/tests/test_port_status.py Implements the Click-tree walk and assertions comparing discovered commands to PORT_STATUS.toml.
PORT_STATUS.toml Defines the baseline inventory of current Click commands and their port status.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mergify_cli/tests/test_port_status.py
Comment thread mergify_cli/tests/test_port_status.py Outdated
Comment thread mergify_cli/tests/test_port_status.py
Comment thread mergify_cli/tests/test_port_status.py Outdated
During the Rust port, any new click command added to the Python CLI
risks being silently missed if the Rust dispatch isn't updated in
parallel. This adds a CI-enforced inventory at the repo root plus
a pytest that walks the click tree and compares against it.

## How it works

``PORT_STATUS.toml`` lists every click subcommand with an explicit
``status`` of either ``native`` (handled by Rust's dispatch) or
``shimmed`` (forwarded to Python by the py-shim crate).
``mergify_cli/tests/test_port_status.py`` walks ``mergify_cli.cli.cli``
and fires four assertions:

- Every discovered click command has an entry.
- Every entry corresponds to a live click command (no stale rows).
- Every entry uses a valid ``status`` value.
- No entry carries extra keys (catches typos like ``stats``).

Forgetting to update the file when adding a new Python command
becomes a CI failure at test-time rather than a "why is this
missing from the binary?" bug report months later.

## Current baseline

All 30 click subcommands are listed. Only ``config validate`` is
``native`` today (from Phase 1.3 in the same stack). The remaining
29 are ``shimmed`` — each subsequent port PR flips its entry from
``shimmed`` to ``native`` in the same commit that adds the Rust
dispatch, keeping the file and the code in lockstep.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Change-Id: I4a71d672f4795dbb3e2e9523ea01b8d7fbbfbcbe
@jd jd force-pushed the devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch from 2521caa to 631557e Compare April 29, 2026 09:06
@mergify mergify Bot deployed to Mergify Merge Protections April 29, 2026 09:07 Active
@mergify mergify Bot requested a review from a team April 29, 2026 09:45
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 29, 2026

Merge Queue Status

  • Entered queue2026-04-29 12:12 UTC · Rule: default
  • Checks skipped · PR is already up-to-date
  • Merged2026-04-29 12:13 UTC · at 631557e0ce75454987482c33f588c425edc86ec0 · squash

This pull request spent 16 seconds in the queue, including 2 seconds running CI.

Required conditions to merge

@mergify mergify Bot merged commit 7fff439 into main Apr 29, 2026
23 checks passed
@mergify mergify Bot deleted the devs/jd/worktree-rust-port/add-port-inventory-guard-catch-un-ported-python--4a71d672 branch April 29, 2026 12:13
@mergify mergify Bot added queued and removed queued labels Apr 29, 2026
mergify Bot pushed a commit that referenced this pull request Apr 29, 2026
Starts distributing the static Rust binary alongside the existing
PyPI wheel. Both pipelines run on every published GitHub Release
until the Phase 1.6 channel switch makes the binary the sole
install path.

## What ships per release

Seven targets as GitHub Release assets, plus matching
``.sha256`` checksum files:

- ``x86_64-unknown-linux-gnu``   (glibc)
- ``x86_64-unknown-linux-musl``  (static)
- ``aarch64-unknown-linux-gnu``  (glibc, ARM server)
- ``aarch64-unknown-linux-musl`` (static, ARM server)
- ``x86_64-apple-darwin``        (Intel macOS, signed + notarized)
- ``aarch64-apple-darwin``       (Apple Silicon, signed + notarized)
- ``x86_64-pc-windows-msvc``     (Windows)

Archives use the ``mergify-<tag>-<target>.tar.gz`` / ``.zip``
naming convention. Linux and Windows builds go through
``taiki-e/upload-rust-binary-action`` which handles
cross-compilation via ``cross`` automatically. macOS builds run
natively on Apple Silicon runners with an explicit pipeline
because of the signing + notarization steps.

## macOS signing / notarization

The macOS job imports a Developer ID Application certificate into
a throwaway keychain, codesigns the binary with the hardened
runtime + timestamp, then submits it to Apple's notarytool
service. Stapling isn't possible on a bare Mach-O; online
Gatekeeper checks approve notarized binaries on first run.

Required GitHub Actions secrets (all six must be set before the
next release):

  APPLE_CERTIFICATE            base64 of the .p12 Developer ID cert
  APPLE_CERTIFICATE_PASSWORD   password set when exporting the .p12
  APPLE_SIGNING_IDENTITY       "Developer ID Application: Mergify SAS (TEAMID)"
  APPLE_API_KEY                base64 of the App Store Connect .p8 API key
  APPLE_API_KEY_ID             10-char key ID from App Store Connect
  APPLE_API_KEY_ISSUER         issuer UUID from App Store Connect

## Install story today

Users grab a binary from the releases page:
``https://github.com/Mergifyio/mergify-cli/releases/latest``.
A ``curl | sh`` installer script + Homebrew tap land in separate
follow-up PRs once we've seen the first binary release succeed.

## Parallel with PyPI

``release.yml`` (existing) keeps publishing to PyPI unchanged.
Both workflows key off the same ``release: published`` event.
The Phase 1.6 channel switch is the user-coordinated moment where
we stop publishing to PyPI and direct users to the binary.

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

Depends-On: #1296
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.

4 participants