Documentation
IntroductionArchitectureMonorepo & ToolingRunning Locally
Screen Flow MapUser JourneysPersonas & RolesWeb ScreensClient Portal
Convex OverviewData ModelFunctions ReferenceAuth & SessionsRoles & PermissionsJobs & Providers
Web Design SystemAdmin Console DesignPatterns & Conventions
Web AppiOS AppMarketing Website
Testing & HarnessCI Pipeline

CI Pipeline

CI Pipeline

v2 CI is one workflow: .github/workflows/v2-tests.yml ("Test: v2"), added with the v2.1 hardening pass. The repo root's other workflows (deploy, devops, release, style, tests) belong to the v1 Laravel app.

Pull request on v2.1**
v2-tests.yml · concurrency cancels superseded runs
Job: check — "typecheck + vitest"
pnpm -C packages/backend typecheck
pnpm -C apps/web exec tsc --noEmit
pnpm -C packages/backend test
27 authz + tenant-isolation cases against an in-memory Convex built from the real schema
Job: e2e — "probe + flows (Playwright)"
convex dev (anonymous) → poll :3210
seed:run {"force": true}
web dev → poll :3200/login
v2-probe.mjs — 34/34 screens clean
v2-flows.mjs — 14/14 flows PASS
✓
both green → mergeable
v2 CI — every v2.1 PR proves typecheck, authz invariants, and the full browser harness in one run

Triggers

  • pull_request (opened / synchronize / reopened) on branches matching v2.1**
  • workflow_dispatch (manual)
  • Concurrency group cancels superseded runs; permissions: contents: read.

Shared setup

pnpm/action-setup@v4 (version read from v2/package.json packageManager) → setup-node@v4 with Node 24 and a pnpm cache keyed on v2/pnpm-lock.yaml → pnpm install --frozen-lockfile.

Job 1: check — "typecheck + vitest"

Runs in v2/:

  1. pnpm -C packages/backend typecheck — tsc --noEmit over the Convex functions
  2. pnpm -C apps/web exec tsc --noEmit — typecheck the product app
  3. pnpm -C packages/backend test — the 27-case authz Vitest suite

Job 2: e2e — "probe + flows (Playwright)"

Stands up the entire stack inside the runner, then runs the harness:

  1. Convex local backend in v2/packages/backend with CONVEX_AGENT_MODE: anonymous (nohup npx convex dev), polling http://127.0.0.1:3210/version for up to ~180s.
  2. Seed: npx convex run seed:run '{"force": true}', retried while the initial function push settles.
  3. Web app in v2/apps/web (pnpm dev) with NEXT_PUBLIC_CONVEX_URL=http://127.0.0.1:3210, polling http://localhost:3200/login.
  4. Playwright installed in tools/walkthrough (npm ci + npx playwright install --with-deps chromium).
  5. node v2-probe.mjs — all 34 screens must render with zero console errors.
  6. node v2-flows.mjs — all 14 business flows must PASS (scripts exit nonzero on FAIL).
  7. On failure: tails the last 100 lines of convex-dev.log and next-dev.log into the job output.

What this buys

Every v2.1 PR proves, in one run: the backend typechecks, the web app typechecks, authorization invariants hold, every screen renders clean against freshly seeded data, and the core business flows — including realtime cross-session updates and the zero-touch portal journey — work end to end in a real browser.

Known scope

  • Only v2.1** branches trigger it; other v2 branches must run the harness locally.
  • The admin console (apps/admin) and website aren't yet in the typecheck matrix — adding pnpm -C apps/admin exec tsc --noEmit to the check job is the natural extension.
  • iOS builds are not in CI (xcodegen + simulator builds run locally).