CI/CD Pipeline
Leadmetrics uses GitHub Actions for continuous integration. The pipeline lives in .github/workflows/pr-validation.yml.
Triggers
| Event | Branches |
|---|---|
| Pull request opened / updated | master, dev |
| Push | master, dev |
Concurrency: one run per branch at a time. If a new push arrives while a run is in progress, the in-progress run is cancelled.
Jobs
1. Lint & Type Check
Runs first. All other jobs depend on this passing.
Checkout → pnpm install → Prisma generate → Type check → Lint| Step | Command | What it checks |
|---|---|---|
| Type check | pnpm typecheck | All packages in the monorepo |
| Lint | pnpm lint | All packages — ESLint rules |
The Prisma client is generated first because typed DB queries won’t compile without it.
2. Unit Tests
Runs after lint & type check passes.
Checkout → pnpm install → Prisma generate → Build packages → Run unit tests| Step | Command | Notes |
|---|---|---|
| Build packages | pnpm build --filter=!api --filter=!dashboard --filter=!dm --filter=!manage | Builds shared packages only (not Next.js apps) |
| Unit tests | pnpm test:unit | All unit tests across the monorepo via Vitest |
What’s Not in CI
| Thing | Why |
|---|---|
| Integration tests | Require a live PostgreSQL database; run locally before merging |
| E2E tests | Require the full 8-service stack; run locally or on a dedicated test server |
| Database migrations | Applied manually or via deploy script on the server |
Deployment
Deployment to production is done via Coolify on DigitalOcean. There is no automated deploy-on-merge pipeline; deployments are triggered manually through the Coolify dashboard.
Each service is deployed as a separate Docker container from the monorepo. The output: "standalone" setting in each Next.js app’s next.config produces a minimal Docker image.
See Infrastructure for the full deployment setup.
Running CI Checks Locally
Before opening a PR, run the same checks locally:
# Type check
pnpm typecheck
# Lint
pnpm lint
# Unit tests
pnpm test:unitIf Prisma client is stale (after a schema change), regenerate first:
cd packages/db && pnpm db:generateBranch Strategy
| Branch | Purpose |
|---|---|
main | Production-ready code |
dev | Integration branch for in-progress features |
| Feature branches | Named feat/..., fix/..., chore/... |
PRs go from feature branches → dev. Promotions from dev → main are done after QA sign-off.