ci: make the frontend gates real, and fix the coverage script

The repo configured four frontend gates and enforced one of them. eslint
and prettier ran in no workflow and no hook; `bun run check` ran only in
build-release.yml, so a type error could sit on master until somebody cut
a tag; and `bun run test:coverage` had been dead for months.

CI (build-and-test.yml) now runs format:check, lint, check and coverage
alongside the existing boundary and doc-link tripwires.

The coverage script failure was a version mismatch, not a config problem:
@vitest/coverage-v8 resolved to 4.1.10, whose peer range pins vitest
exactly, while package.json asked for ">=1.0.0 <5.0.0" and got 4.0.16 --
every run died on a missing BaseCoverageProvider export. The loose range
is what allowed the pair to drift, so it is now ^4.1.10.

Two ratchets, same policy as MIN_THRESHOLD in traceability-check.yml:

  eslint  --max-warnings=159   (0 errors; 159 is today's backlog, only
                                ever lower it)
  vitest  thresholds           (statements 51 / branches 45 /
                                functions 46 / lines 52, measured at
                                54.6 / 48.7 / 49.6 / 55.1)

no-console is promoted from "off" to "error": the logger-facade
migration it was waiting on is finished -- 8 calls remained, 2 of them
real stragglers in the settings page, now on the facade the file already
imported. The sink itself, tests, and scripts/ are exempted; a CLI whose
stdout is the product is not a stray debug statement.

The threshold was verified to bite by raising it to 99 and watching the
run go red, not by assuming an unfailed gate works.

DR-205 moves to Done; the coverage gate is DR-215.
This commit is contained in:
2026-08-21 18:11:26 +02:00
parent ad48d89dfe
commit 8f5c9023d0
9 changed files with 122 additions and 38 deletions
+12 -6
View File
@@ -21,7 +21,8 @@ bun run check # svelte-check (types)
bun run test # vitest (frontend unit/integration)
bun run test:rust # cargo test (scripts/test-rust.sh)
bun run test:all # full suite (scripts/test-all.sh)
bun run test:e2e # webdriverio e2e
bun run lint # eslint (src/, scripts/, root configs)
bun run format:check # prettier
# Android — canonical entry points (see scripts/):
bun run android:build # debug APK
@@ -61,7 +62,8 @@ only against the mirror if one exists; the canonical remote is
## Before Committing
- Frontend: `bun run check` and `bun run test` must pass.
- Frontend: `bun run check`, `bun run test`, `bun run format:check` and
`bun run lint` (0 errors; the warning count is a CI ratchet) must pass.
- Rust: `cd src-tauri && cargo fmt` then `cargo clippy`, plus `bun run test:rust`.
- **Boundary**: `bun run check:boundary` must pass — no domain taxonomy (Jellyfin
item-type category sets) leaked into the frontend. See below.
@@ -112,10 +114,12 @@ rename that missed a call site can no longer pass silently.
**CI is Gitea Actions** (`.gitea/workflows/`, remote `gitea.tourolle.paris`), not
GitHub. `traceability-check.yml` fails the build if coverage drops below
**82%** (`MIN_THRESHOLD`, a *ratchet* — raise it as coverage climbs, never lower
**88%** (`MIN_THRESHOLD`, a *ratchet* — raise it as coverage climbs, never lower
it to make a build pass) or if any traced ID is undefined; `build-and-test.yml`
runs frontend + Rust tests, `cargo fmt --check`, an advisory `cargo clippy`, and
an Android `cargo check`. See [docs/traceability-ci.md](docs/traceability-ci.md)
runs frontend tests **with coverage thresholds**, `bun run check`, `format:check`,
a `--max-warnings` eslint ratchet, Rust tests, `cargo fmt --check`, `cargo clippy
-D warnings`, and an Android `cargo check`. See
[docs/traceability-ci.md](docs/traceability-ci.md)
and [docs/traces-quick-ref.md](docs/traces-quick-ref.md).
### Traces drive release notes
@@ -212,7 +216,9 @@ and [docs/build/build-release.md](docs/build/build-release.md).
## Writing specs
New feature specs go in [docs/specs/](docs/specs/). **Start from
New feature specs go in [docs/specs/](docs/specs/) — see its
[README](docs/specs/README.md) for the index and what is already built.
**Start from
[SPEC-TEMPLATE.md](docs/specs/SPEC-TEMPLATE.md)** — its "Layer assignment" section
forces each piece of *logic* to be placed in the correct layer (Rust = domain,
frontend = presentation) *with a reason*, which is what prevents boundary leaks.