What Exists Today
Every stage of a pipeline already runs locally via workspace scripts:
| Stage | Command | What it covers |
|---|---|---|
| Install | pnpm install --frozen-lockfile |
Reproducible dependency tree |
| Typecheck | pnpm typecheck |
tsc/vue-tsc across all three packages |
| Test | pnpm test |
Vitest — protocol suite (crypto, worker, channels) + server suite (endpoint, services, rules) |
| Build | pnpm build |
Production client bundle |
| DB | pnpm db:migrate / db:seed |
Schema migrations + demo data |
CI is therefore composition, not invention.
Proposed Workflow
# proposed: .github/workflows/ci.yml
name: CI
on:
push: { branches: [main] }
pull_request:
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: 22, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm typecheck
- run: pnpm test
env:
ENCRYPTION_KEY: ${{ secrets.TEST_ENCRYPTION_KEY }}
- run: pnpm build
image:
needs: verify
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/build-push-action@v6
with:
push: true
tags: ghcr.io/${{ github.repository }}/server:${{ github.sha }}
Deployment then follows the topology from Cloud Architecture: the image rolls out to the container platform; the client build uploads to the CDN.
Design Choices
- One
verifyjob, not a matrix. The monorepo’s packages share a lockfile and node version; splitting jobs per package would triple setup time to parallelize seconds of work. - Tests need a key. The server suite boots the real agent, so CI supplies
a dedicated
TEST_ENCRYPTION_KEYsecret — never the committed dev key, and never a production one. - Migrations as a release step.
pnpm db:migrateruns against the target database before the new image receives traffic, replacing the current migrate-on-boot convenience flag. - Image tagged by SHA. Rollback is redeploying a previous tag — no special tooling.
Release Gates
- Pull request →
verifymust pass (typecheck, both test suites, build). - Merge to
main→ image built and pushed. - Deploy → migrations, then rollout, watching the
io/pingliveness route. - Rollback trigger: elevated
unknown-type error replies or failed pings (see Monitoring & Logs).