GitHub Workflows¶
Overview of the GitHub Actions workflows in .github/workflows/. They cover deployment,
releases, PR checks, preview environments, tests, and docs.
Keep this in sync
This page mirrors the workflow files. When you add, rename, or retrigger a workflow, update the matching row in the same PR.
Deployment¶
One pipeline per environment, shipping the whole platform in a single gated run. main →
Production, develop → Staging, or manually via workflow_dispatch. There are deliberately
no per-app deploy workflows and no per-app path filters.
| Workflow | File | Trigger | Description |
|---|---|---|---|
| Deploy - Production | deploy-production.yml |
Push main / manual |
Calls deploy.yml with environment: production. Concurrency group never cancels in progress. |
| Deploy - Staging | deploy-staging.yml |
Push develop / manual |
Calls deploy.yml with environment: staging. Ignores docs-only pushes; cancels superseded runs. |
| Deploy | deploy.yml |
workflow_call |
The pipeline itself: builds all five components and runs the backend suite, applies Terraform, deploys the backend, verifies it, then deploys the three hosting targets and verifies the members and clinicians apps. Rolls Cloud Run traffic back if backend verification fails, and always closes the deployment record, posts to Slack and emits a single DORA event for the release. |
See Deployments for the shape and Rollback runbook for recovery.
Release management¶
See Branching & releases for the flow these drive.
| Workflow | File | Trigger | Description |
|---|---|---|---|
| Cut Release | cut-release.yml |
Manual | Cuts a release/X.Y.Z branch from develop and opens the release PR to main. |
| Back Merge Main to Develop | back-merge.yml |
Push main |
Opens/updates the sync/main-to-develop PR so main and develop don't diverge after a release. |
| Release PR Guard | release-pr-guard.yml |
PR | Guards PRs targeting main: enforces release/* or hotfix/* branch naming and the required app version bumps. |
PR checks¶
Run on pull requests to gate merges.
| Workflow | File | Trigger | Description |
|---|---|---|---|
| CI - Backend | ci-backend.yml |
PR | Lint, test, and build for the backend packages; the required Backend checks passed gate. |
| CI - Flutter | ci-flutter.yml |
PR | Analyze, test, coverage, and tag-vocabulary lint for the Flutter apps and shared packages; the required Flutter checks passed gate. |
| Check Android Build | mobile-build-staging-apps.yml |
Push/PR develop |
Verifies the Android build compiles for Members & Clinicians (path-filtered to native/gradle/pubspec changes). |
| Terraform - Plan | terraform-plan.yml |
PR (non-draft) | Runs terraform plan for the staging and production workspaces on infrastructure/terraform/** changes; fails the check on plan errors so infra issues surface before merge. |
| Workflows - PR Checks | workflow-lint.yml |
PR | Runs actionlint and zizmor over .github/workflows/** and .github/actions/**. No workflow-level path filter, so the Workflow checks passed gate is always reported and can be required by a ruleset. |
| Engineering Docs | docs.yml |
PR / push develop |
Builds the docs site --strict on PR (via uv); deploys to Cloudflare Pages on merge to develop. |
Preview environments¶
| Workflow | File | Trigger | Description |
|---|---|---|---|
| Preview - Backend and Apps | preview-pr.yml |
PR (pull_request_target) |
Creates preview environments for Backend (Cloud Run) and the Members/Clinicians apps (Firebase Hosting channels), deploying only changed components. |
| Preview - Cleanup Resources | preview-cleanup.yml |
PR closed | Tears down the Cloud Run services, Docker images, and caches for a closed PR. |
| Preview - Janitor | preview-janitor.yml |
Schedule (Sun 03:00 UTC) / manual | Sweeps orphaned preview resources after loading the open PR list from GitHub; manual runs support a dry-run input. |
See Preview environments.
Tests & health checks¶
| Workflow | File | Trigger | Description |
|---|---|---|---|
| E2E - Web | e2e-web.yml |
PR into main or release/*; any PR that edits the Patrol tests |
Patrol E2E (Chrome/Playwright), webSafe-tagged subset, one matrix job per app. Release candidates run both apps unconditionally, against the candidate's own preview backend (it waits for preview-pr.yml's backend deploy for that head sha, and fails rather than fall back to staging). A PR that edits patrol_test/, the shared harness or this lane's CI definition also runs, for the app(s) whose tests changed, against staging. Every other PR gets no E2E lane; e2e-web-nightly.yml covers the gap. |
| E2E - Web Autofix | e2e-web-autofix.yml |
Called by e2e-web.yml on failure |
Agentic Patrol-failure triage: classifies flake vs real break, opens a draft fix PR, re-runs the failing target as the gate. |
| Security Audit Autofix | security-audit-autofix.yml |
Called by ci-backend.yml when the Security Audit fails |
Agentic pnpm audit fix: raises the pnpm overrides on develop, gates on the audit and a frozen install, opens one draft fix PR for all failing PRs. |
| E2E - Web Nightly | e2e-web-nightly.yml |
Nightly cron / manual | The webSafe Patrol subset for both apps against real staging; advisory (not a required check). Not wired to pull requests: PRs into main and release/* already run the same subset through e2e-web.yml. |
| E2E - Native | e2e-native-manual.yml |
PR to main / manual |
Patrol on Android via Firebase Test Lab. Release and hotfix PRs into main run the full native matrix automatically (members Stripe purchase on a phone; clinicians video/in-call and the native file picker on a tablet), seeding their own staging fixtures. Manual dispatch still takes either app, any branch, a single target or tags selector with optional FTL sharding. Native checks passed is the required check — never rename it. |
| Manual - BFF API Health Check | manual-api-health-check.yml |
Manual | EchoAPI scenarios against the Member or Clinical BFF (choice input). |
| Coverage - develop baseline | coverage-develop.yml |
Push develop |
Re-runs both test suites after a merge and uploads coverage to Datadog under the flutter / backend-functions flags, giving PR coverage a default-branch baseline to diff against. Tests only - no lint or gate - and never blocks a merge. |
Utility¶
| Workflow | File | Trigger | Description |
|---|---|---|---|
| Validate Google Secrets | validate-google-secrets.yml |
Push develop/main / manual |
Checks the GCP Secret Manager secrets referenced by the functions exist (path-filtered to secrets config). |