Commit Graph

14 Commits

Author SHA1 Message Date
didericis-codex f5fec38ca8 ci: scope firecracker backend to integration coverage
test / integration-firecracker (pull_request) Successful in 10s
test / integration-docker (pull_request) Successful in 23s
test / unit (pull_request) Successful in 36s
tracker-policy-pr / check-pr (pull_request) Successful in 11s
test / coverage (pull_request) Failing after 3h1m9s
2026-07-18 21:43:43 +00:00
didericis 319cac85b8 ci: drop dev-requirements pip install on the self-hosted KVM runner
test / integration-firecracker (pull_request) Successful in 12s
test / integration-docker (pull_request) Successful in 28s
test / unit (pull_request) Successful in 37s
test / coverage (pull_request) Failing after 3h12m24s
The self-hosted runner's Nix python env has no `pip` module, so
`python3 -m pip install -r requirements-dev.txt` failed with "No module
named pip" in both firecracker jobs. Neither job needs that install:

- integration-firecracker runs the stdlib `unittest` suite (no deps);
- coverage needs only `coverage`, which the runner's Nix python env
  already ships (7.12.0) — verified `coverage run`/`coverage json` work.

pylint/pyright are lint.yml's concern, not test.yml's. The ubuntu-latest
`unit` job keeps its `--break-system-packages` install unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1qRZTJC6qgBsUSjNrBdkX
2026-07-18 17:02:40 -04:00
didericis-claude 5624025b02 ci(test): split integration into per-backend jobs
test / integration-docker (pull_request) Successful in 9s
test / unit (pull_request) Successful in 30s
lint / lint (push) Successful in 2m24s
tracker-policy-pr / check-pr (pull_request) Failing after 11s
test / integration-firecracker (pull_request) Has been cancelled
test / coverage (pull_request) Has been cancelled
Add separate `integration-docker` and `integration-firecracker` jobs,
each with an explicit BOT_BOTTLE_BACKEND env var, so the backend used
is visible in CI output and skipped backends surface as a distinct job
rather than silent unittest.skip lines.

- integration-docker: ubuntu-latest, BOT_BOTTLE_BACKEND=docker
- integration-firecracker: [self-hosted, kvm], BOT_BOTTLE_BACKEND=firecracker,
  same-repo PRs + push + workflow_dispatch only (untrusted fork PRs do
  not execute on the privileged KVM runner)
- coverage: same same-repo restriction; refs #414 for the planned
  follow-up that moves coverage to ubuntu-latest via artifact combination

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-18 14:46:38 -04:00
didericis-claude df24e5e955 ci(coverage): address review findings from PR #349
- Finding 1: set BOT_BOTTLE_BACKEND=firecracker on the coverage step so
  the integration suite actually exercises the Firecracker orchestration
  paths rather than defaulting to Docker
- Finding 2: restrict the coverage job to push+workflow_dispatch only;
  PR-controlled code no longer executes on the privileged KVM runner
  automatically — maintainers trigger workflow_dispatch for trusted PRs
- Finding 3: expand path filters to include workflow files, scripts, and
  README so changes to CI configuration trigger the workflow itself

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-18 14:46:38 -04:00
didericis-claude ea147edb6f ci(coverage): install dev requirements on the KVM runner
The self-hosted KVM runner is a persistent machine, so
--break-system-packages is inappropriate. Use --user instead so
coverage (and pyright/pylint for future jobs) land in ~/.local
and survive between runs without touching the system Python.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-18 14:46:38 -04:00
didericis 2b4382bce9 ci(coverage): run the diff-coverage gate on a self-hosted KVM runner
Re-land the coverage gate deferred from #343. The Firecracker VM/SSH
orchestration (~230 lines) is only exercised by the integration suite,
which needs /dev/kvm + the provisioned TAP/nft pool — a container runner
skips it and those lines read uncovered, so the 90% diff gate can't pass
on ubuntu-latest. Move the `coverage` job to a self-hosted `kvm` runner
with a firecracker-readiness preflight (binary + /dev/kvm + `backend
status`) so the integration test actually runs. Unit/lint stay on
ubuntu-latest. README documents the runner prerequisites.

Depends on a registered self-hosted runner labelled `kvm`; until one is
provisioned this gate will not run. See PRD 0069 / #348.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
2026-07-18 14:46:38 -04:00
didericis d3c4fc0fd4 ci(test): drop actions/setup-python; install into the container's system Python
test / integration (pull_request) Successful in 7s
test / unit (pull_request) Successful in 44s
test / coverage (pull_request) Successful in 36s
test / integration (push) Successful in 7s
Update Quality Badges / update-badges (push) Failing after 11s
test / unit (push) Successful in 29s
test / coverage (push) Successful in 35s
lint / lint (push) Successful in 2m24s
The old act_runner engine (v0.2.13 on the delphi-ci runner) mishandles
actions/setup-python's PATH injection: pip installs coverage into the
toolcache interpreter while `python3` in later steps resolves back to the
image's system Python, so unit/coverage jobs failed with "No module named
coverage". Newer runners (TrueNAS's v0.6.1) don't, which is why it only
broke on delphi.

The runner-images/act container already ships Python 3.12, and the job
container is ephemeral, so drop setup-python entirely and install straight
into the system Python with --break-system-packages. Every step now uses
one interpreter consistently, on any runner version. Also removes the
redundant setup-python step from the integration job (stdlib-only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UoEZHDjv84ChoZbozQERhJ
2026-07-18 04:58:38 -04:00
didericis b2f498cac5 ci(coverage): defer the KVM-runner diff-coverage gate
lint / lint (push) Successful in 1m57s
test / unit (pull_request) Successful in 55s
test / integration (pull_request) Successful in 18s
test / coverage (pull_request) Successful in 58s
Split the self-hosted KVM runner setup out of this branch so main's CI
doesn't require a runner that isn't registered yet. The `coverage` job
runs on ubuntu-latest again and reports combined coverage informationally
— the hard diff-coverage gate (which needs the firecracker integration
suite, hence /dev/kvm + the provisioned pool) is deferred and moves to a
separate PR. The unit-coverage tests added alongside the gate stay.

See PRD 0069 / #348; the runner + gate re-land on the ci-runner branch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
2026-07-12 16:44:18 -04:00
didericis c44a1ffdc1 ci(coverage): run the diff-coverage gate on a KVM runner
lint / lint (push) Successful in 2m3s
test / unit (pull_request) Successful in 1m0s
test / integration (pull_request) Successful in 16s
test / coverage (pull_request) Has been cancelled
The Firecracker VM/SSH orchestration (launch/boot/SSH/isolation-probe,
~230 lines) is covered by the integration suite, which needs /dev/kvm +
the provisioned pool — a container runner skips it, so those lines read
uncovered and the 90% diff gate can't pass there (it's been red since the
backend landed). Move the `coverage` job to a self-hosted `kvm` runner
with a firecracker-readiness preflight (binary + /dev/kvm + `backend
status`), so the integration test actually runs and the orchestration is
covered. Unit/lint stay on ubuntu-latest. README documents the runner
prerequisites.

Also close the last unit-coverable gaps (bottle exec/close, bottle_plan
properties, docker status/setup branches, netpool span/conflict) so the
gate clears 90% (90.3%) with the firecracker integration test running.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
2026-07-12 15:55:39 -04:00
didericis 632ab002ed ci(coverage): risk-weighted coverage policy + diff-coverage gate
test / unit (pull_request) Successful in 46s
test / integration (pull_request) Successful in 16s
test / coverage (pull_request) Successful in 1m2s
lint / lint (push) Successful in 2m16s
test / unit (push) Successful in 59s
test / integration (push) Successful in 29s
test / coverage (push) Successful in 1m9s
Update Quality Badges / update-badges (push) Failing after 2m9s
Adopt ADR 0004: stop chasing a single global coverage number and
measure what matters instead.

- Omit the genuinely-interactive `cli/init.py` shell (read_tty_line
  prompt loops) alongside the existing `cli/tui.py`, with a rationale
  comment in .coveragerc. Subprocess/backend orchestration is NOT
  omitted — it stays visible and is scored via the integration suite.
- scripts/coverage.sh runs unit + integration under one coverage
  measurement (the policy's yardstick) and can report the critical
  security/logic core held to the >=90% target.
- scripts/diff_coverage.py is a stdlib-only gate (no diff-cover dep):
  new/changed executable lines must be >=90% covered. This is the
  enforced regression guard; the global number is informational.
- CI gains a `coverage` job: combined report + the diff-coverage gate.
- Unit-test `cli/__init__.py` dispatch/exit-code mapping (it's logic,
  not I/O, so it earns tests rather than an omit).

Combined unit+integration coverage now reports 83% global / 87% across
the critical modules; per-module ratcheting toward 90% is the ongoing
work this policy frames.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkwFXLFff9PYPy4wgVBJp9
2026-06-25 21:29:08 -04:00
didericis 8188d6304e ci: add coverage.py reporting 2026-06-25 15:03:06 -04:00
didericis 0fbf2ab513 feat(ci): only run tests on .py file changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 00:42:40 -04:00
didericis 4462863d56 test: reorganize suite into unit/integration/canaries directories
Replace the hand-maintained INTEGRATION_NAMES classifier (and the
bespoke run_tests.py around it) with a directory-driven split:

  tests/unit/         unit tests, always run
  tests/integration/  Docker-dependent, skip cleanly without Docker
  tests/canaries/     upstream-regression checks, opt-in via
                      CLAUDE_BOTTLE_RUN_CANARIES=1

The pinned-pipelock-image check moves to the canary suite — it tests
upstream packaging, not our code, so it shouldn't gate every dev push.
A scheduled canaries.yml workflow runs it weekly.

The manifest-runtime tests collapse the four assertRaises cases for
distinct 'runtime' values into one subTest loop and drop the
error-message-wording assertions; the contract is "any value is
rejected", not "the error literally contains 'auto-detect'".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 16:23:02 -04:00
didericis 4694db1201 PRD 0002: Test pipeline on Gitea Actions (#3)
test / run tests/run_tests.py (push) Successful in 20s
2026-05-09 02:48:03 -04:00