ci: run integration tests on the forge runner; keep publish gated on unit tests #57

Merged
mph merged 1 commit from ci/drop-itest-publish-gate into main 2026-07-17 14:45:38 +00:00
Owner

Summary

Two related CI changes for the Forgejo migration:

  1. Integration tests now run on CI. They never did — ci.yml and publish.yml both only ran __.test. This adds a dedicated itest job to ci.yml (needs: compile) that runs ./mill __.itest on every PR.
  2. Publish stays gated on __.test only (commit ed12dd2) — itest is a PR gate, not a publish gate.

Why the --init container

__.itest spawns real OS processes. direct.itest's ProcessManagerTest cleanup tests count system-wide zombies and expect them to return to baseline, which needs a zombie-reaping init as PID 1. On the forge runner the job container's PID 1 is the job shell (no reaper), so those assertions fail where they pass on a full VM.

The itest job runs in container: catthehacker/ubuntu:act-latest (the runner's ubuntu-latest label mapping) with options: --init, so tini runs as PID 1 and reaps the orphaned sh/sleep children the timeout/failure tests leave behind.

No secrets needed

Every test that drives the real Claude CLI is a guarded *E2ETest that self-skips via assume(isClaudeCliInstalled(), ...) when claude is absent (PATH-only probe, catches all exceptions → munit ignores). All other itests use mock CLI scripts or deliberately-failing commands. So the itest job needs no API key or CLI install.

Publishing (unchanged)

publish.yml already targets both registries: Forgejo Maven on every main push + tags, Maven Central (PGP-signed) on v* tags only.

Validation

  • Verified statically: only guarded E2E tests touch the real CLI; the rest are mock-based.
  • Not validated locally: that act_runner honors container.options: --init — a local Docker test can only confirm tini reaps zombies, not the runner integration. The first run of this PR's itest job is the real check.
  • Heads-up: ProcessManagerTest."should cleanup process resources when process execution fails" is a known occasional timing flake under parallel load, independent of this change.

🤖 Generated with Claude Code

## Summary Two related CI changes for the Forgejo migration: 1. **Integration tests now run on CI.** They never did — `ci.yml` and `publish.yml` both only ran `__.test`. This adds a dedicated `itest` job to `ci.yml` (`needs: compile`) that runs `./mill __.itest` on every PR. 2. **Publish stays gated on `__.test` only** (commit `ed12dd2`) — itest is a PR gate, not a publish gate. ## Why the `--init` container `__.itest` spawns real OS processes. `direct.itest`'s `ProcessManagerTest` cleanup tests count *system-wide* zombies and expect them to return to baseline, which needs a zombie-reaping init as PID 1. On the forge runner the job container's PID 1 is the job shell (no reaper), so those assertions fail where they pass on a full VM. The `itest` job runs in `container: catthehacker/ubuntu:act-latest` (the runner's `ubuntu-latest` label mapping) with `options: --init`, so tini runs as PID 1 and reaps the orphaned `sh`/`sleep` children the timeout/failure tests leave behind. ## No secrets needed Every test that drives the real Claude CLI is a guarded `*E2ETest` that self-skips via `assume(isClaudeCliInstalled(), ...)` when `claude` is absent (PATH-only probe, catches all exceptions → munit ignores). All other itests use mock CLI scripts or deliberately-failing commands. So the itest job needs no API key or CLI install. ## Publishing (unchanged) `publish.yml` already targets both registries: Forgejo Maven on every `main` push + tags, Maven Central (PGP-signed) on `v*` tags only. ## Validation - Verified statically: only guarded E2E tests touch the real CLI; the rest are mock-based. - **Not validated locally:** that `act_runner` honors `container.options: --init` — a local Docker test can only confirm tini reaps zombies, not the runner integration. The first run of this PR's `itest` job is the real check. - Heads-up: `ProcessManagerTest."should cleanup process resources when process execution fails"` is a known occasional timing flake under parallel load, independent of this change. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ci: run integration tests on the forge runner with an init reaper
Some checks failed
CI / Check Formatting (pull_request) Successful in 47s
CI / Compile (pull_request) Successful in 1m1s
CI / Check Linting (pull_request) Successful in 43s
CI / Run Tests (pull_request) Successful in 57s
CI / Run Integration Tests (pull_request) Failing after 1m34s
d6148d62fc
Integration tests never ran in CI: ci.yml only ran __.test and publish.yml
gates on __.test. Add a dedicated itest job (needs: compile) that runs
__.itest on every PR.

__.itest spawns real OS processes; its ProcessManager cleanup tests count
system-wide zombies and expect them to return to baseline, which needs a
zombie-reaping init as PID 1. The forge runner's job container has the job
shell as PID 1, so start the container with `--init` (tini) to reap the
orphaned children the timeout/failure tests leave behind. Pin the container
image to the runner's ubuntu-latest label mapping so `--init` applies to a
concrete container.

The E2E tests that drive the real Claude CLI gate on its availability and
skip when it is absent, so no API key or CLI install is needed on CI.
Publishing to both Maven Central (tags) and the Forgejo registry (every
main push) is already wired in publish.yml and is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mph force-pushed ci/drop-itest-publish-gate from d6148d62fc
Some checks failed
CI / Check Formatting (pull_request) Successful in 47s
CI / Compile (pull_request) Successful in 1m1s
CI / Check Linting (pull_request) Successful in 43s
CI / Run Tests (pull_request) Successful in 57s
CI / Run Integration Tests (pull_request) Failing after 1m34s
to 14cffbef08
All checks were successful
CI / Check Formatting (pull_request) Successful in 38s
CI / Compile (pull_request) Successful in 53s
CI / Check Linting (pull_request) Successful in 47s
CI / Run Tests (pull_request) Successful in 1m1s
CI / Run Integration Tests (pull_request) Successful in 1m25s
2026-07-17 11:36:40 +00:00
Compare
mph merged commit 229b2668c2 into main 2026-07-17 14:45:38 +00:00
mph deleted branch ci/drop-itest-publish-gate 2026-07-17 14:45:38 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
iterative-works/claude-code-query!57
No description provided.