Quality

CI/CD

The jobs that run on a pull request, when each one runs, and how to add one.

The jobs

Every pull request runs .github/workflows/ci.yml on GitHub Actions:

JobWhat it checks
Lint, deps, formatoxlint, syncpack, Prettier, the client env allowlist, and generated files against their sources
Backend testsThe full Vitest suite
Storybook testsEvery play test in Chromium
SemgrepThe rule tests, then the scan
ZAP scan and signed-in CSPThe web app's CSP, signed out and signed in, then ZAP against a running stack
Accessibility and CSPThe accessibility sweep, and the CSP on every static page
BuildsThe web app, marketing site, blog, and docs, then the secrets scan of their output

A draft runs nothing. Detect changes skips on a draft, and every other job needs it. Marking the pull request ready runs everything.

When a job runs

The first job, Detect changes, lists the pull request's files and decides which checks they affect. Every other job reads its list and skips when it isn't there.

Each check has a pattern in the paths map at the top of ci.yml. A pattern includes the check's own files and every workspace it imports, so a shared-ui change reruns the web-app build. Root files — package.json, yarn.lock, the workflows — run everything. Markdown only counts for formatting.

A manual run from the Actions tab runs every check.

Add a check

  1. Add an area to the paths map in the Detect changes job, with a pattern for every file it reads.
  2. Add a step to an existing job, or a new job with needs: changes and an if: on the area.
  3. Use ./.github/actions/setup for Node and dependencies. Pass playwright: "true" if it needs Chromium.

Put a new job in its own job when its failure means something different from its neighbors'. An accessibility failure isn't a broken build, so it has its own job.

Artifacts

Each build is uploaded for three days as <app>-pr-<number>, and older uploads from the same pull request are deleted. The accessibility and ZAP jobs upload their reports as a11y-report and zap-report.

CD

Nothing runs on merge yet. There's no deploy target, so there's nothing for a deploy job to do. Hosting is decided — see AWS.

Also not built:

  • Desktop builds. A Tauri build needs Rust and system libraries, and would be its own workflow.
  • Required checks. Branch protection isn't turned on, so a failing check doesn't block a merge.
  • CI/CD — what runs, and why only what changed.
  • GitHub Actions — how the workflow is shaped.
  • Testing — running the tests yourself.