Skip to main content
Restricted Access: This documentation is only accessible to @tenzo.ai and @salv.ai email addresses.

Summary

GitHub CI (.github/workflows/ci.yaml) skips the server or UI job on pull requests when that tree did not change. Pushes to main always run both. The merge gate remains a full suite for whichever side ran — we do not select individual pytest cases from the diff in CI.

What runs when

Detection mirrors codegen.yaml: git diff against the PR base SHA (or the previous commit on push), with a safe fallback to “run everything” when the base SHA is missing. Required check names stay stable via lightweight aggregators:
  • server (3.10) — passes when both server-checks (lint, typecheck, migrations) and server-tests shards succeed or server work was skipped
  • ui (22) — passes when both ui-lint-typecheck and ui-tests succeed or UI work was skipped
Both aggregators fail closed if the changes job itself did not succeed (empty skip outputs must not greenlight a merge with zero tests).

Why not “only tests that touch changed code” as the CI gate

Locally, server/bin/test --testmon (and --fail-fast) can rerun only tests that import changed modules. That is intentional as a local accelerator, not a merge gate:
  • testmon needs a persisted .testmondata map; cold CI caches still run everything first
  • It is incompatible with pytest-xdist / pytest-cov as used in the full suite
  • Shared helpers, fixtures, migrations, and config can break distant tests that a naive path or import map misses
Safer layers:
  1. Path-level job skip (what CI does now) — don’t spin server runners for a UI-only PR
  2. Optional local / future pre-check--fail-fast or cached testmon before the full suite
  3. Full suite for the side that changed — and always on main

Local fast loop

From server/:
See the header comments in server/bin/test for details and constraints.