Pipeline Overview
CI/CD pipeline structure -- five jobs, their triggers, dependencies, timeouts, and the path from push to production.
Trovella's CI/CD pipeline runs in GitHub Actions as a single workflow (.github/workflows/ci.yml). Every push and PR triggers quality checks. Merges to main additionally build a Docker image, optionally migrate the production database, and deploy to the production VM.
The pipeline was restructured from a monolithic 11-minute sequential job into parallel jobs that complete in ~3.5 minutes. See ADR-012: CI/CD Pipeline for the decision history.
Pipeline Structure
Five jobs with explicit dependency gates:
push / PR to main
|
+---> quality (15 min) --------+-----------> deploy-prod (10 min)
| | ^
+---> docs (5 min) | |
| v |
+---> build-push (15 min) -----+--------------------+
(main only) |
v
migrate-prod (5 min)
(main only)
deploy-prod requires three upstream jobs to pass: quality, build-push, and migrate-prod. The docs job runs independently and does not gate deployment.
Job Summary
| Job | Trigger | Depends On | Gates Deploy? | Timeout |
|---|---|---|---|---|
quality | All pushes and PRs | None | Yes | 15 min |
docs | All pushes and PRs | None | No | 5 min |
build-push | Main branch only | None (parallel) | Yes | 15 min |
migrate-prod | Main branch only | quality | Yes | 5 min |
deploy-prod | Main branch only | quality + build-push + migrate-prod | N/A (is the deploy) | 10 min |
Typical wall-clock time from merge to live: 5--10 minutes.
Trigger Conditions
The workflow fires on two events:
pushtomain-- triggers all five jobs (quality, docs, build-push, migrate-prod, deploy-prod)pull_requesttargetingmain-- triggers onlyqualityanddocs
The build-push, migrate-prod, and deploy-prod jobs have an explicit condition:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
This means PR branches only run quality checks -- they never build Docker images or touch production infrastructure.
Service Containers
The quality job starts three service containers for integration tests:
| Service | Image | Port | Health Check |
|---|---|---|---|
| PostgreSQL 18 | pgvector/pgvector:pg18 | 5433 | pg_isready every 5s |
| Redis 8 | redis:8-alpine | 6379 | redis-cli ping every 5s |
| Typesense 27.1 | typesense/typesense:27.1 | 8108 | None (starts quickly) |
These containers run on the GitHub Actions runner alongside the job steps. They are ephemeral -- destroyed when the workflow completes.
Artifacts
Two artifacts are uploaded (with 14-day retention):
| Artifact | Job | Condition | Contents |
|---|---|---|---|
jscpd-report | quality | Always (even on failure) | HTML duplication report |
docs-freshness-report | docs | Always (even on failure) | JSON stale-docs report |
Pages in This Topic
- Job Definitions -- what each job does, step by step, with environment variables and permissions
- Quality Checks -- the 10 checks in the quality job, their order, and why order matters
- Concurrency & Caching -- cancel-in-progress, Turborepo
--affected, BuildKit cache layers - Local CI Parity --
pnpm ci:check, pre-commit hooks, and keeping local/CI in sync - ADR-012: CI/CD Pipeline -- decision record for the pipeline structure
Cross-Domain References
- Infrastructure -- Deploy Pipeline -- step-by-step deploy process (SCP, SSH, container restart)
- Infrastructure -- Workload Identity -- how CI authenticates to GCP without service account keys
- Infrastructure -- CI Secret Access -- how CI reads secrets from GCP Secret Manager
- Data & Storage -- CI Deployment -- the
migrate-prodjob in detail (proxy setup, migration execution, verification)