CI/CD Pipeline
PSI uses GitHub Actions for continuous integration and deployment. The pipeline ensures code quality, runs tests, and automates deployments.
Pipeline Overview
graph LR
subgraph "On Every Push / PR"
CHECK[check.yml<br/>Format, Lint, Typecheck]
TEST[test.yml<br/>Unit Tests]
E2E[e2e.yml<br/>End-to-End Tests]
end
subgraph "On PR (Client Changes)"
PREVIEW[firebase-pull-request.yml<br/>PR Preview Deploy]
end
subgraph "After E2E on main"
STAGING[firebase-staging.yml<br/>Deploy to Staging]
end
CHECK --> E2E
TEST --> E2E
E2E -->|"main branch"| STAGING Workflows
check.yml -- Code Quality
Triggers: Push to main, Pull Requests
Runs in parallel, filtered by changed paths:
| Job | Runs When | Checks |
|---|---|---|
| Formatting | Any change | Biome format check |
| Client lint + typecheck | Client changes | ESLint + TypeScript compiler |
| Server lint + typecheck | Server changes | ESLint + TypeScript compiler |
| Translation checks | Translation changes | Missing/unused translation keys |
test.yml -- Unit Tests
Triggers: Push to main, Pull Requests
| Job | Runs When | Framework |
|---|---|---|
| Client tests | Client changes | Jest 29, @testing-library/react |
| Server tests | Server changes | Jest 29, ts-jest |
| Server MongoDB tests | Server changes | Jest 29 with MongoDB memory server |
On PRs, client tests only run for changed files (--changedSince). On main, all tests run.
e2e.yml -- End-to-End Tests
Triggers: Push to main, Pull Requests
Full integration tests using Puppeteer:
- Build client (
pnpm run webbuild) - Build server (
pnpm run build) - Start Firebase emulators (Auth, RTDB, Functions, Hosting)
- Start publisher demo server
- Run Puppeteer test suite
firebase-pull-request.yml -- PR Preview
Triggers: Pull Requests with client changes
Deploys a preview of the client to a Firebase Hosting preview channel:
- URL:
https://np-psi-staging--pr-{number}-{hash}.web.app - Only client (hosting) is deployed; server changes aren't reflected
- Preview channels cleaned up via
firebase-hosting-cleanup.yml
firebase-staging.yml -- Staging Deploy
Triggers: After successful E2E on main, or manual dispatch
Deploys both client and server to the staging environment (np-psi-staging):
- Builds Storybook
- Builds client (
pnpm run webbuild) - Builds server (
pnpm run build) - Deploys to Firebase (hosting + functions)
Required Secrets
| Secret | Used By | Purpose |
|---|---|---|
FIREBASE_SERVICE_ACCOUNT | Staging deploy, PR preview | Firebase deployment credentials |
OPENAI_KEY | E2E tests | AI moderation in tests |
Service Account Roles
For CI/CD deployment, the service account needs:
- Cloud Functions Developer
- Cloud RuntimeConfig Admin
- Firebase Hosting Admin
- Firebase Realtime Database Admin
- Service Account User
For PR preview deployments, additionally:
- Firebase Authentication Admin
- Service Usage Consumer
Further Reading
- Environments -- all deployment targets
- Automated Tests (psi-product) -- test writing guide
- Pull Requests (psi-product) -- PR workflow