Local CI/CD Guide¶
CI is confirmation, not discovery.
Catch everything locally first. If remote CI fails, a local check was skipped.
Where Things Live¶
.husky/
pre-commit ← fires on every git commit
pre-push ← fires on every git push
.actrc ← act image + architecture config
.github/workflows/ci.yml ← the real pipeline (lint → build → test → docker → deploy)
What to Run¶
pnpm run lint # ESLint across all apps
pnpm run build # Turborepo build (dependency order respected)
pnpm run test:unit # Jest unit + integration (no e2e)
pnpm run act # simulate the full CI job locally
Always use pnpm run act, not plain act
Plain act queues the docker, deploy, and notify jobs which require secrets and will fail or push images. pnpm run act scopes to -j ci only.
Git Hooks¶
- Blocks commits to
main,master,dev- use a feature branch. - Runs
lint-staged- Prettier, ESLint, secretlint on staged files. - Type-checks staged TypeScript - only the app(s) with staged
.ts/.tsxfiles.
- Passes protected branches through (
main,master,dev) - no checks. - Enforces branch naming on all other branches:
<type>/<description>
| type | feat, fix, chore, refactor, hotfix, docs, test |
|---|---|
| description | Lowercase, digits, hyphens. No leading/trailing hyphens. |
✅ feat/add-user-auth ✅ fix/login-redirect
❌ feature/AddUserAuth ❌ myBranch
What to Worry About¶
CI job order
ci (lint → build → test)
└── docker ← push events only, needs ci to pass
└── deploy ← dev branch only
└── notify (Discord)
ci passes. Definition of Done¶
Pre-Push Checklist
- [ ] Branch name follows
<type>/<description>. - [ ]
pnpm run lintpasses. - [ ]
pnpm run buildpasses. - [ ]
pnpm run test:unitis fully green. - [ ] E2E tests pass locally (
pnpm --filter e2e run test). - [ ] Branch is up-to-date with
dev.