CI-CD Workflows

19 GitHub Actions workflow files in .github/workflows/ automate testing, building, and deployment.

Core Pipeline

WorkflowTriggerPurpose
main-deploy.ymlPush to mainBuild, test, deploy to development
pr-preview.ymlPR open/updateOrchestrator: preview deployment + all CI via reusable workflows + ci-gate
pr-cleanup.ymlPR closeDestroy preview app, ephemeral DB, Tigris objects, Entra redirect URI
promote-image.ymlManual dispatchPromote images: -f promotion_path="development → staging" / "staging → production", optional image_digest pin

Reusable Workflows (workflow_call)

Called from pr-preview.yml (and main-deploy.yml) — they no longer trigger standalone on PRs:

WorkflowPurpose
quality-checks.ymlTypecheck, lint, backend/frontend tests in 3-way shards, coverage merge + diff-coverage, Storybook build gate (PR#1958), localized-text, i18n parity, migration-consistency, persistence-topology gate (I#2013), changelog-check, e2e-warmup-script tests
docker-build.ymlBuild + push container images
e2e-tests.ymlPlaywright e2e against the preview app, behind a blocking warmup gate (PR#1949)
migration-tests.ymlMigration validation incl. N-1 gate — runs when schema/migration files change
container-security-scan.ymlTrivy container vulnerability scan on built images
security-scan.ymlPR-gate security scans (also has its own daily 02:00 UTC cron)

Security Workflows

WorkflowTriggerPurpose
security-scan.ymlworkflow_call from PR pipeline + daily 02:00 UTCPR-gate scans: Trivy, npm/bun audit, Semgrep, Gitleaks (HIGH/CRITICAL block)
security-scan-scheduled.ymlDaily 02:00 UTC + Mondays 08:00 UTCTwo-track policy: MEDIUM+ findings → tracking issues + auto-ignore PRs; Monday run posts the weekly Teams digest
container-security-scan.ymlworkflow_call on image buildTrivy container-specific scan

Database Workflows

WorkflowTriggerPurpose
migration-tests.ymlworkflow_call from pr-preview.ymlMigration syntax, ordering, destructive ops, N-1 gate
staging-db-sync.ymlNightly 03:00 UTC + manualProduction → staging sync (DB + Tigris)
backup-verify.ymlWeekly (Sundays 03:00 UTC)Verify backup integrity

Maintenance Workflows

WorkflowTriggerPurpose
cleanup-registry.ymlDaily 03:00 UTCPrune old container images
cleanup-orphaned-previews.ymlDaily 02:00 UTCRemove stale preview apps
cache-warmup.ymlDaily 04:00 UTCWarm application caches

Other Workflows

WorkflowTriggerPurpose
claude.yml@claude mentions in issues/PRs/reviewsClaude Code GitHub action (interactive agent)
deploy-log-shipper.ymlPush + manualDeploy log shipping infrastructure
sync-project.ymlPush + manualSync issues to GitHub Projects

Required Status Check

The ci-gate job (in pr-preview.yml) is the single required status check for merging. It needs: detect-changes, quality-checks, security-scanning, migration-validation, build, deploy-preview, e2e-tests, and container-security-scan, and validates each passed or was correctly skipped (docs-only changes skip the app pipeline; security and migration results always block on failure). See Git Workflow for branch protection rules.

Secrets in CI

App secrets are not GitHub environment secrets (fixed in PR#1930). Infisical EU is the source of truth: development/staging/production sync natively to Fly.io; CI fetches the pr-preview scope via OIDC (Infisical/secrets-action) and stages them with flyctl secrets set --stage. GitHub Actions secrets hold CI-infra credentials only (FLY_API_TOKEN, FLY_MPG_TOKEN, …).

Image Tags

Tag PatternSource
main-<sha>Main branch builds
dev-latest / *-latestLatest build per environment (scheduled scans target these)
pr-<number>PR preview builds

Promotion Flow

development --> staging --> production
  (auto)       (manual)    (manual)
gh workflow run promote-image.yml -f promotion_path="development → staging"
# optionally pin: -f image_digest=sha256:…

Same immutable Docker image is promoted across environments. Rollback re-promotes the previous digest — see Deployment Rollback.

See Also