Skip to content

Commit 9e9cae5

Browse files
jdclaude
andauthored
test(live): port func-tests/ from pytest to a cargo integration test (#1606)
The Python `func-tests/test_live_smoke.py` was the last non-vendored Python in the repo — a pytest harness driving the real `mergify` binary against the canary repo's Mergify API endpoints. Now that every command is native, the test runner itself is the only thing keeping `setup-python` in CI. Port the 10 tests + the conftest fixtures to a cargo integration test at `crates/mergify-cli/tests/live_smoke.rs`. 1:1 with the Python version on contract — same scrubbed env list, same assertion messages, same skip-on-missing-token behaviour. The JUnit fixture moves to `crates/mergify-cli/tests/fixtures/` so cargo packages it consistently. Notable bits: - `env!("CARGO_BIN_EXE_mergify")` for the binary path — cargo sets it at compile time so the test can't accidentally pick up an installed binary on `$PATH`. - Token-gated tests early-return after `eprintln!("SKIP: ...")`. Cargo's stock harness has no "skip" outcome; surfacing the skip in stderr (visible under `cargo test -- --nocapture`) means a missing-secret regression in CI can't slip past as a silent green. - Cleanup runs from `Drop` (queue unpause; freeze delete) so a mid-test assertion failure still leaves the canary repo in the state we found it. Warn (don't panic) inside `drop` so a cleanup-time issue can't mask the real test failure. - `wait_timeout` polls `Child::try_wait` to mirror Python `subprocess.run(timeout=30)`; pulls in no new crate. Kills and panics on timeout so a hung binary fails fast instead of riding cargo's longer wall-clock. CI workflow trimmed: drops `setup-python`, drops the `pip install pytest` step, drops `PATH` plumbing for the built binary. Test runner is `cargo test --release --test live_smoke -- --nocapture`. The release build path is the one whose binary the contract is pinned against — debug builds would skip the `strip` step that `build-wheels.yml` enables in production. Local verification (Linux/macOS, no tokens set): the 3 hermetic tests pass, the 8 token-gated tests each log `SKIP: live_(admin_)token() (env var unset)` and early-return. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 9552f3c commit 9e9cae5

6 files changed

Lines changed: 829 additions & 794 deletions

File tree

.github/workflows/func-tests-live.yaml

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Live functional tests
33
# Hits the real Mergify API against
44
# mergify-clients-testing/mergify-cli-repo PR #1. Runs on every PR.
55
# NOT wired into the PR `ci-gate` job — an upstream blip must not
6-
# block PRs. See `func-tests/test_live_smoke.py`.
6+
# block PRs. See `crates/mergify-cli/tests/live_smoke.rs`.
77

88
permissions: read-all
99

@@ -17,42 +17,32 @@ jobs:
1717
environment: func-tests-live
1818
steps:
1919
- uses: actions/checkout@v6.0.3
20-
- uses: actions/setup-python@v6.2.0
21-
with:
22-
python-version: 3.14
2320

2421
- name: Install Rust toolchain
2522
run: |
2623
rustup toolchain install stable --profile minimal
2724
rustup default stable
2825
- uses: Swatinem/rust-cache@v2
2926

30-
- name: Build mergify binary
31-
run: cargo build --release
32-
33-
- name: Put built binary on PATH
34-
run: echo "${PWD}/target/release" >> "${GITHUB_PATH}"
35-
3627
- name: Live smoke tests
37-
shell: bash
3828
env:
3929
# Two tokens with different scopes:
4030
# - _CI exercises CI-tooling endpoints (scopes-send,
4131
# junit-process). ci git-refs / queue-info are
4232
# locally evaluated and need no token at all.
4333
# - _ADMIN exercises every endpoint under /merge-queue/
44-
# (status, show, pause, unpause). The CI token is
45-
# rejected with 403 on these, so they all share the
46-
# queue-management-scoped admin token.
47-
# Tests select the appropriate fixture; absent tokens
48-
# cause individual tests to skip rather than fail.
34+
# (status, show, pause, unpause) and the
35+
# /scheduled_freeze endpoints (list, create, update,
36+
# delete). The CI token is rejected with 403 on these,
37+
# so they all share the queue-management-scoped admin
38+
# token.
39+
# Tests early-return with `SKIP:` when their token is
40+
# unset rather than failing — local runs without secrets
41+
# still produce a useful subset.
4942
LIVE_TEST_MERGIFY_TOKEN_CI: ${{ secrets.MERGIFY_CLI_LIVE_TEST_MERGIFY_TOKEN_CI }}
5043
LIVE_TEST_MERGIFY_TOKEN_ADMIN: ${{ secrets.MERGIFY_CLI_LIVE_TEST_MERGIFY_TOKEN_ADMIN }}
51-
# Use `pip install pytest` over an ephemeral `uv tool run`
52-
# so the func-tests don't drag any package-management
53-
# tool into the supported-runtime contract. The wheel
54-
# itself has no Python deps; pytest only matters here as
55-
# the test runner.
56-
run: |
57-
pip install --user 'pytest>=8'
58-
python -m pytest -v func-tests/ -m live
44+
# `--nocapture` so the `SKIP:` lines stay visible — without
45+
# it, cargo eats stderr on passing tests and a silently-
46+
# skipped run on a missing-secret regression would look
47+
# green.
48+
run: cargo test --release --test live_smoke -- --nocapture
File renamed without changes.

0 commit comments

Comments
 (0)