CI Integration
How tests run in GitHub Actions -- service containers, the --affected optimization, pre-commit hooks, and the path from local to CI.
Tests in the CI Pipeline
Tests run in the quality job of .github/workflows/ci.yml. The job runs on every push and every PR targeting main.
The test step uses Turborepo's --affected flag to run only tests for packages that changed:
- name: Test
run: pnpm turbo test --affected
This means a PR that only modifies packages/ai will only run @repo/ai tests, not the full suite. Turborepo determines "affected" by comparing the current commit against the merge base.
Service Containers
The quality job starts three service containers alongside the runner for integration tests:
| Service | Image | Port | Used By |
|---|---|---|---|
| PostgreSQL 18 | pgvector/pgvector:pg18 | 5433 | @repo/db RLS tests |
| Redis 8 | redis:8-alpine | 6379 | @repo/cache tests |
| Typesense 27.1 | typesense/typesense:27.1 | 8108 | @repo/search tests |
The PostgreSQL container includes the pgvector extension, matching the production Cloud SQL configuration. Health checks on PostgreSQL and Redis ensure the containers are ready before tests start.
Database migrations run before tests:
- name: Migrate database
run: pnpm db:migrate
This applies all schema changes and RLS policies to the CI PostgreSQL instance so that RLS integration tests run against real, up-to-date policies.
Why Real PostgreSQL in CI?
The PostgreSQL service container was added specifically because RLS tests cannot be mocked. The critical RLS bug in TRO-10 -- where tenantProcedure silently bypassed all RLS policies by passing the bare db pool instead of the transaction-scoped tx -- validated this decision. The service container adds approximately 10 seconds to CI startup. See ADR-014 for the full decision rationale.
Environment Variables in CI
The quality job sets environment variables that match the service container configuration:
env:
DATABASE_URL: postgresql://trovella:trovella_dev@localhost:5433/trovella
REDIS_URL: redis://localhost:6379
BETTER_AUTH_SECRET: ci-test-secret-at-least-32-characters-long
BETTER_AUTH_URL: http://localhost:3000
GOOGLE_CLIENT_ID: ci-placeholder
GOOGLE_CLIENT_SECRET: ci-placeholder
ANTHROPIC_API_KEY: ci-placeholder
GOOGLE_AI_API_KEY: ci-placeholder
TYPESENSE_API_KEY: ci-test-key
TYPESENSE_URL: http://localhost:8108
Non-secret values use ci-placeholder or ci-test-* values. The DATABASE_URL matches the PostgreSQL service container's credentials and port.
Pre-Commit Hooks
Pre-commit hooks run via Husky and lint-staged. The .lintstagedrc.mjs configuration runs ESLint and Prettier on staged files, grouped by their nearest package directory:
export default {
"*.{ts,tsx}": (files) => {
const byPackage = groupByPackage(files);
const commands = [];
for (const [pkgDir, pkgFiles] of byPackage) {
commands.push(`node scripts/lint-staged-eslint.mjs "${pkgDir}" ${fileArgs}`);
}
commands.push(`prettier --write ${files.join(" ")}`);
return commands;
},
"*.{js,jsx,mjs,cjs,json,md,mdx,yml,yaml,css}": "prettier --write",
};
Note: pre-commit hooks run linting and formatting, not tests. Tests run via pnpm ci:check (manual) or in CI.
Local CI Parity
Before pushing, run pnpm ci:check to match CI quality checks locally:
# Runs: format, lint, dep-cruise, dead code, duplication,
# typecheck, test, doc-update-detection
pnpm ci:check
# Full CI parity including build
pnpm ci:full
The test step within ci:check runs pnpm turbo test, which runs all package tests. For faster iteration during development, run tests for a single package:
pnpm turbo test --filter=@repo/ai
CI Coverage Gates -- Descoped
Per-package coverage thresholds in CI were descoped in favor of mutation testing as the primary quality signal. The plan is to add a minimal CI check that flags new source files with zero test coverage. See ADR-014 for the rationale.
Currently, coverage data is generated on demand via pnpm test:coverage and analyzed by trovella-test-audit, not as a CI gate.
Test Order in CI
Within the quality job, the test step runs after linting, type-checking, and database migration:
- Install dependencies (
pnpm install --frozen-lockfile) - Lint (
pnpm turbo lint --affected) - Type-check (
pnpm turbo typecheck --affected) - Migrate database (
pnpm db:migrate) - Test (
pnpm turbo test --affected) - Build (
pnpm turbo build --affected)
Tests run after migration so that the PostgreSQL service container has the latest schema and RLS policies applied. Tests run before build so that test failures surface before the slower Docker image build.
Test Audit CLI
Reference for the trovella-test-audit CLI tool -- coverage aggregation, source-to-test mapping, and mutation testing across the monorepo.
Dependency Management Overview
How Trovella manages third-party dependencies across the monorepo -- pnpm catalog, Renovate automation, and version strategy.