Skip to content
Русский

7. CI

  • GitHub Actions from the start (right after the workspace scaffold): a runner for every shipped standalone platform — Windows, macOS and Linux — running cargo build, cargo nextest run, cargo test --doc, cargo clippy --all-targets -- -D warnings, cargo fmt --all --check on every push. All of those carry --workspace since ADR-0072, and it is load-bearing rather than stylistic: rlx-core-cabi is deliberately outside the workspace default-members, so the bare forms would silently stop testing and linting the C ABI entirely.
  • Plus the single-runner gates: cargo deny check (supply chain), Miri over rlx-ring’s unsafe (UB), the coverage ratchet below, the studio job (the studio’s typecheck, lint and Vitest suite — the only automated reading of studio/, since the pre-push hook’s studio step skips itself on a clone with no studio/node_modules), and the Node doc gates that share the links job — check-doc-links.mjs (every relative markdown link resolves — Plan 0061 Phase 2c), check-index-rows.mjs (every row inside a marked roster region stays a pointer under 320 bytes — ADR-0116), check-backlog-claims.mjs (every live backlog entry’s probe still holds — ADR-0108), check-filter-figures.mjs (the diffusion filter’s cost figures live in one page — ADR-0122), check-comment-hygiene.mjs (no .rs comment carries a relative link or plan-relative narration — ADR-0127), toc.mjs (every generated contents block still matches the headings beneath it — ADR-0163), check-reader-prose.mjs (every Plan/ADR citation in a reader document sits inside a link — ADR-0168), check-release-tag.mjs (the version main declares carries an annotated tag — ADR-0203), and check-translations.mjs (every .ru.md carries the stamp of the commit it was translated from — ADR-0185). More invocations than gates: check-index-rows.mjs, toc.mjs, check-release-tag.mjs and check-translations.mjs each run a --self-test beside their check, because neither a detector that has quietly stopped matching nor an anchor rule that is merely plausible is visible in the check itself.
  • The nine GPU-heavy suites run once per push, not twice (ADR-0073, Plan 0061 Phase 2b). They render the shipped preset library on WARP, and until that change ran uninstrumented in check (windows-latest) and instrumented in coverage at the same moment on two identical runners (≈ 1930 duplicated CPU- seconds). check now carries the same exclusion .githooks/pre-push does, which makes coverage the only place they execute on Windows — so that job is load-bearing for correctness, not only for the ratchet. Disabling it, skipping it, or letting cargo-llvm-cov fail to install takes the golden guard and every GPU behavioural suite with it.
  • Live audio cannot run in CI. GPU rendering partly can: on Windows the DX12 WARP software adapter makes headless rendering deterministic, which is what the golden suite and the tier-4 chain test ride on. macOS has no software Metal fallback (ADR-0016), so the GPU suites skip there with a printed reason. Real-GPU-vendor and live-loopback checks stay manual — see On-device validation.
  • Coverage ratchet (ADR-0033): a Windows-only job runs cargo llvm-cov nextest -p rlx-core --fail-under-lines $COVERAGE_FLOOR, and since ADR-0072 a second, smaller gate beside it on -p rlx-core-cabi against $CABI_COVERAGE_FLOOR — without which the C ABI’s coverage would silently stop being watched the moment it left rlx-core. Neither gates standalone/: it is a winit event loop plus two platform capture backends no runner can execute. Both floors live in exactly one place, the env: block in ci.yml, and are a ratchet, not a target: set from measurement, raised at a close ceremony when a plan improves coverage, lowered only with a note naming the plan and the reason. COVERAGE_FLOOR was 88 from Plan 0032’s measured 90.13 %, and is 91 since Plan 0061 Phase 2 — a moved denominator, not better tests, since ffi.rs and its conformance suite left the gated crate. That 91 was measured on the dev box, which has a hardware GPU where CI has WARP, so it is owed a re-derive from a cache-warm CI run (Plan 0061 Phase 9, outstanding); the margin is ~3 points rather than the usual 2 for exactly that reason. CABI_COVERAGE_FLOOR is 54 against a measured 56.60 %, and it is low because most of core-cabi is error, null-handle and catch_unwind paths — recorded to catch a regression, not claimed as good coverage. A line-coverage floor is gameable by design — it is a backstop against silent erosion, not a quality measure. The Mode 4 review’s “read the assertion body” step remains the actual quality gate.
  • Local pre-push gate (opt-in, per clone): .githooks/pre-push, enabled with git config core.hooksPath .githooks. Runs the fast subset — the Node doc gates, fmt, clippy --workspace, and a narrowed nextest --workspace -P fast — whose fast profile (ADR-0156) is where the excluded GPU-heavy suites are listed, and which nextest names on every run. Measured 48.6 s warm (2026-08-08, dev box), against the ~28 s recorded when ADR-0033 set it up. The number drifted with the suite it runs, not with the gate’s design; it is recorded here rather than targeted, and the README’s developer section carries the per-step breakdown. If it grows past the point where people start reaching for --no-verify, that is the signal to narrow it further — ADR-0033’s own argument is that a gate which hurts gets disabled. cargo deny, doctests, Miri, and coverage stay in CI. An uninstalled clone silently has no gate; see the README’s developer section. Every Node gate (check-doc-links.mjs ~50 ms, check-index-rows.mjs, check-backlog-claims.mjs, check-filter-figures.mjs, check-comment-hygiene.mjs, toc.mjs, check-reader-prose.mjs, check-release-tag.mjs, check-translations.mjs) also runs as the CI links job (ubuntu-latest), so they are enforced for everyone rather than only where the hook is installed — and they skip together with a notice when node is absent, which is the ADR-0016 shape.

Built from 13c7582 at version 0.158.0. This site tracks main and is not versioned per release.