Three related fixes from the test audit. **The CLI journey fixture gets its own database.** It spawned a real picloud — whose dispatcher/orchestrator claim loops are global by design (one instance owns one database) — against the shared dev DB, so it could claim the manager-core suites' outbox/workflow rows (the same class of bug already fixed for the e2e suites, one binary over). It now clones one dedicated database per journey run from the migrated template. test-support gains `named_test_db_url` (explicit stable name) + a blocking wrapper for the sync `LazyLock` fixture. The one journey that talks to Postgres directly (dead-letter injection) now uses the fixture's DB URL, not the base DATABASE_URL, so it hits the database the server reads. **workflow_orchestrator moves to per-test databases.** Its `claim_ready_step` is global, so the old harness serialized every test behind a process-wide CLAIM_LOCK AND ran `DELETE FROM workflow_runs` (unscoped — it wiped every app's runs) before each one. A private database per test makes the global claim see only that test's rows, so both the lock and the unscoped DELETE are deleted. **DB-backed suites fail loud instead of skipping green.** ~15 manager-core suites `return None` when DATABASE_URL is unset and report PASS — so in any environment that lost its database the entire integration surface reports green while running nothing (why the CI gap went unnoticed for so long). New `picloud_test_support::abort_if_db_required` panics when `PICLOUD_REQUIRE_DB` is set (CI now sets it) but DATABASE_URL is not, injected into each suite's skip path. Local runs without the var still skip cleanly. Mutation-verified: with PICLOUD_REQUIRE_DB=1 and DATABASE_URL unset, a suite panics; without the var it skips. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
116 lines
4.5 KiB
YAML
116 lines
4.5 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
# Matches what docker-compose produces locally; the schema-snapshot
|
|
# guardrail and any other DB-backed tests run against this service.
|
|
DATABASE_URL: postgres://picloud:picloud@localhost:5432/picloud
|
|
# The DB-backed suites skip themselves when DATABASE_URL is unset. In CI it is
|
|
# always set, so this makes that skip a hard error: if the database ever goes
|
|
# missing (a broken service container, a lost env), the build goes RED instead
|
|
# of green-but-empty. Honored by picloud_test_support::abort_if_db_required.
|
|
PICLOUD_REQUIRE_DB: "1"
|
|
|
|
jobs:
|
|
rust:
|
|
name: Rust — fmt, clippy, test
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: postgres:15
|
|
env:
|
|
POSTGRES_USER: picloud
|
|
POSTGRES_PASSWORD: picloud
|
|
POSTGRES_DB: picloud
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd "pg_isready -U picloud"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# rust-toolchain.toml pins the channel; this action honors it.
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@stable
|
|
with:
|
|
components: rustfmt, clippy
|
|
|
|
- name: Cache cargo
|
|
uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Format check
|
|
run: cargo fmt --all -- --check
|
|
|
|
- name: Clippy
|
|
run: cargo clippy --all-targets --all-features -- -D warnings
|
|
|
|
# `--include-ignored` is load-bearing. Every DB-backed integration test is
|
|
# `#[ignore = "needs DATABASE_URL..."]`, and CI omitted the flag — so CI ran
|
|
# 927 tests and silently skipped 237, among them ALL of authz.rs and api.rs
|
|
# and the entire CLI journey suite. The isolation and RBAC tests existed but
|
|
# never executed (AUDIT.md F-Q-014). CI does provide Postgres, so run them.
|
|
#
|
|
# `--all-targets` (not a bare `cargo test`) is deliberate: it runs the lib,
|
|
# bins, and integration tests but NOT doctests. `-- --include-ignored`
|
|
# un-ignores not just `#[ignore]` tests but also ` ```ignore ` DOCTESTS,
|
|
# which are illustrative pseudocode that does not compile — so a bare
|
|
# `cargo test ... -- --include-ignored` fails on them. Doctests run in their
|
|
# own step below, without the flag. (Clippy already uses `--all-targets` for
|
|
# the same doctest-excluding reason.)
|
|
#
|
|
# The CLI journeys are a SEPARATE step, and deliberately not part of the
|
|
# workspace run: they spawn a real picloud whose dispatcher/orchestrator
|
|
# claim loops are global by design (one instance owns one database). Run
|
|
# concurrently with the manager-core suites — which share this database —
|
|
# it would claim their outbox and workflow rows out from under them. Keeping
|
|
# the steps sequential keeps that live server off the shared DB while the
|
|
# other suites are using it.
|
|
- name: Test (workspace, including DB-backed tests)
|
|
run: cargo test --workspace --exclude picloud-cli --all-targets -- --include-ignored
|
|
|
|
# Doctests, run WITHOUT --include-ignored so ` ```ignore ` snippets stay
|
|
# ignored. `--all-targets` above skips these, so nothing else covers them.
|
|
- name: Doctests
|
|
run: cargo test --workspace --doc
|
|
|
|
# The journey harness execs the prebuilt target/debug/picloud and does NOT
|
|
# rebuild it, so a stale binary would silently test old server code.
|
|
- name: Build picloud (the journey harness execs this binary)
|
|
run: cargo build -p picloud
|
|
|
|
# The spawned server inherits this env; without a secret key it aborts at
|
|
# startup and every journey fails as "/healthz never returned 200".
|
|
# `--all-targets` for the same reason as above (the journeys are `#[ignore]`
|
|
# integration tests; picloud-cli's doctests, if any, run in the Doctests step).
|
|
- name: Test (CLI journeys)
|
|
env:
|
|
PICLOUD_DEV_MODE: "true"
|
|
PICLOUD_DEV_INSECURE_KEY: i-understand-this-is-insecure
|
|
run: cargo test -p picloud-cli --all-targets -- --include-ignored
|
|
|
|
dashboard:
|
|
name: Dashboard — check
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: dashboard
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 20
|
|
cache: npm
|
|
cache-dependency-path: dashboard/package-lock.json
|
|
- name: Install deps
|
|
run: npm ci
|
|
- name: Svelte check
|
|
run: npm run check
|