CI-CD Workflows
19 GitHub Actions workflow files in .github/workflows/ automate testing, building, and deployment .
Core Pipeline
Workflow Trigger Purpose main-deploy.ymlPush to main Build, test, deploy to development pr-preview.ymlPR open/update Orchestrator: preview deployment + all CI via reusable workflows + ci-gate pr-cleanup.ymlPR close Destroy preview app, ephemeral DB, Tigris objects, Entra redirect URI promote-image.ymlManual dispatch Promote 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:
Workflow Purpose 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 changecontainer-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
Workflow Trigger Purpose 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 UTC Two-track policy : MEDIUM+ findings → tracking issues + auto-ignore PRs; Monday run posts the weekly Teams digestcontainer-security-scan.ymlworkflow_call on image buildTrivy container-specific scan
Database Workflows
Workflow Trigger Purpose migration-tests.ymlworkflow_call from pr-preview.ymlMigration syntax, ordering, destructive ops, N-1 gatestaging-db-sync.ymlNightly 03:00 UTC + manual Production → staging sync (DB + Tigris) backup-verify.ymlWeekly (Sundays 03:00 UTC) Verify backup integrity
Maintenance Workflows
Workflow Trigger Purpose cleanup-registry.ymlDaily 03:00 UTC Prune old container images cleanup-orphaned-previews.ymlDaily 02:00 UTC Remove stale preview apps cache-warmup.ymlDaily 04:00 UTC Warm application caches
Other Workflows
Workflow Trigger Purpose claude.yml@claude mentions in issues/PRs/reviewsClaude Code GitHub action (interactive agent) deploy-log-shipper.ymlPush + manual Deploy log shipping infrastructure sync-project.ymlPush + manual Sync 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, …).
Tag Pattern Source main-<sha>Main branch builds dev-latest / *-latestLatest build per environment (scheduled scans target these) pr-<number>PR preview builds
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