Deployment¶
This project utilizes GitHub Actions for automated deployments to Staging and Production environments. The workflows are configured to deploy different components of the application: App (Vercel), Supabase Migrations, aiHub (AWS Fargate), and the API Gateway Authorizer Lambda (AWS Lambda).
Environments¶
- Staging: Deployed from the
stagingbranch. Used for testing and QA before promoting to production. - Production: Deployed from the
mainbranch. This is the live environment.
Workflow Triggers¶
All deployment workflows can be triggered in two ways:
- Automatic:
- Pushing changes to the
stagingbranch will trigger the corresponding Staging deployment workflows if relevant paths are modified. - Pushing changes to the
mainbranch will trigger the corresponding Production deployment workflows if relevant paths are modified. - Manual:
- All deployment workflows can be manually triggered from the GitHub Actions tab in the repository. This is useful for re-deploying or for out-of-band deployments. This was enabled by adding
workflow_dispatch:to each workflow file.
Vercel git-triggered deployments are disabled¶
GitHub Actions is the ONLY deploy path for the app. The Vercel project stays linked to the GitHub repo (for deployment metadata), but its automatic per-push deployments are turned off via "git": { "deploymentEnabled": false } in packages/app/vercel.json — the file must live in the project's Root Directory (packages/app), not the repo root, or Vercel ignores it. CLI deployments from the workflows (vercel build + vercel deploy --prebuilt) are unaffected by this setting. See Vercel git configuration docs.
Before this flag, every push created a phantom git deployment that the ignored-build-step (exit 0 in the project settings) immediately cancelled — and pushes whose commit author's GitHub account wasn't linked to a Vercel team member showed up as BLOCKED deployments with an "add <user> to your team" banner. Those blocked entries were cosmetic (nothing was built or deployed), but the flag stops them being created at all. Do NOT "fix" a blocked deployment by adding the author to the Vercel team — team membership is not required when all deploys go through the workflows' shared VERCEL_TOKEN.
Workflow Files¶
The deployment workflows are located in the .github/workflows/ directory:
- App (Vercel):
deploy-app-staging.ymldeploy-app-production.yml- Supabase Migrations:
deploy-supabase-migrations-staging.ymldeploy-supabase-migrations-production.yml- aiHub (AWS Fargate):
deploy-aihub-fargate-staging.ymldeploy-aihub-fargate-production.yml- API Gateway Authorizer Lambda (AWS Lambda):
deploy-authorizer-lambda-staging.ymldeploy-authorizer-lambda-production.yml- aiHub SQS Processor Lambda (AWS Lambda):
deploy-aihub-sqs-processor-lambda-staging.ymldeploy-aihub-sqs-processor-lambda-production.yml- Storybook (Vercel):
deploy-storybook.yml
Feature Promotion Flow¶
Features move from staging to production using the dual-PR workflow:
- Developer merges PR #1 to
staging→ staging deploys, UAT begins - UAT passes → developer merges PR #2 (same branch) to
main→ production deploys - After main merge,
post-main-merge.ymlauto-syncs main into staging and deletes the feature branch
This allows selective production promotion — each feature ships independently.
Hotfixes¶
For urgent production fixes, developers PR directly to main (skip staging). The post-main-merge.yml workflow auto-syncs the fix into staging.
Staging Hygiene¶
The reset-staging.yml workflow (manual trigger) resets staging to match main and re-merges any features still in UAT. Run periodically to clean up shipped/abandoned features.
Supporting Workflows¶
post-main-merge.yml— Auto-syncs main into staging after each main merge, deletes feature branchesreset-staging.yml— Smart staging reset with auto-re-merge of in-progress features
See docs/development/GIT_WORKFLOW.md for the full developer workflow guide.
App Build Performance (Vercel deploys)¶
The app deploy workflows build on the GitHub Actions runner (vercel build, then vercel deploy --prebuilt) — Vercel's own build machines and their "Build Machine" size setting are NOT involved. Two optimizations keep the Build Project Artifacts step fast (it was ~9 min: 3.9 min compile + 3.8 min in-build typecheck):
-
The in-build TypeScript pass is skipped on deploys.
next.config.mjssetstypescript.ignoreBuildErrorsonly whenCI_SKIP_BUILD_TYPECHECK=true, which onlydeploy-app-staging.yml/deploy-app-production.ymlset. This is safe only because the deployed SHA already passedyarn typecheckin PR checks — if you ever remove the typecheck from PR checks, removeCI_SKIP_BUILD_TYPECHECKfrom the deploy workflows too. Local and PR-check builds still typecheck. -
Turbopack's filesystem build cache is persisted between deploys.
experimental.turbopackFileSystemCacheForBuild(next.config.mjs) writes intermediate compilation artifacts topackages/app/.next/cache, and the deploy workflows restore/save it viaactions/cachewith per-environment keys (next-build-staging-…/next-build-production-…— kept separate because each environment inlines differentNEXT_PUBLIC_*values). Restore falls back to the latest previous deploy's cache; only changed modules (and their dependents) recompile.
Caveat — the Turbopack build cache is a beta feature (Next 16). Correctness is content-hash based, so a stale artifact shouldn't be reusable, but if a deploy ever behaves in a way the source can't explain, suspect the cache first:
- Reset: bump the cache key prefix in BOTH deploy-app workflows (e.g.
next-build-→next-build-v2-) and re-run the deploy — this forces a cold build (~4 min compile instead of warm). Alternatively delete the specific cache entries under the repo's Actions → Caches UI. - A cache miss is always safe (just slower); the failure mode to watch for is a wrong reuse, which the key bump eliminates.
- If the beta flag itself misbehaves (build crashes referencing the cache), remove
turbopackFileSystemCacheForBuildfromnext.config.mjs— the cache steps then become harmless no-ops.
Configuration¶
For the deployment workflows to run successfully, necessary secrets and variables must be configured in your GitHub repository settings:
- Repository Secrets: Go to
Settings>Secrets and variables>Actions. - Configure secrets like
VERCEL_TOKEN,SUPABASE_ACCESS_TOKEN,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, etc. - Environment Secrets & Variables: Some workflows are tied to GitHub Environments (e.g., "Production", "Staging"). Secrets and variables specific to these environments should be configured there.
- Go to
Settings>Environments. Select an environment (or create one if it doesn't exist, matching theenvironment:name in the workflow files). - Add environment-specific secrets (e.g.,
STAGING_SUPABASE_DB_PASSWORD) and variables (e.g.,STAGING_VERCEL_PROJECT_ID).
Refer to the original structure of each workflow YAML file or the respective service deployment guides (Vercel, Supabase, AWS) for details on the specific secrets and variables required for each.
Storybook Deployment¶
The Storybook deployment provides a separate documentation site for your UI components, deployed to its own Vercel project.
Setup Instructions¶
1. Create a New Vercel Project for Storybook¶
- Go to Vercel Dashboard
- Click "Add New..." → "Project"
- Import your repository (same repo as your main project)
- Configure the project:
- Project Name:
delta-storybook(or your preferred name) - Framework Preset: Other
- Root Directory:
packages/app - Build Command:
yarn build-storybook - Output Directory:
storybook-static - Install Command:
yarn install
2. Configure GitHub Secrets¶
Add the following secrets to your GitHub repository:
- Go to your GitHub repository
- Navigate to Settings → Secrets and variables → Actions
- Add the following repository secrets:
VERCEL_STORYBOOK_PROJECT_ID: Your Storybook project ID- Found in your Vercel project settings for the Storybook project
3. How to Find Vercel Project ID¶
- Go to your Storybook project in Vercel
- Go to "Settings"
- The Project ID is shown in the "General" tab
4. Deployment Process¶
The GitHub Action will automatically:
- On Pull Requests: Deploy a preview version of Storybook
- On Main Branch: Deploy to production
The workflow triggers when changes are made to:
packages/app/src/components/**packages/app/.storybook/**packages/app/src/styles/**
Local Development¶
To run Storybook locally:
cd packages/app
yarn storybook
This will start Storybook on http://localhost:6006
To build Storybook locally:
cd packages/app
yarn build-storybook
Adding New Stories¶
- Create a
.stories.tsxfile next to your component - Follow the pattern in
src/components/ui/Button.stories.tsx - The story will automatically be picked up by Storybook
Benefits of This Setup¶
- Consistency: Uses the same GitHub Actions approach as your other deployments
- Automatic Deployments: Deploys on every relevant change
- Preview Deployments: Get preview URLs for pull requests
- Separate Project: Keeps Storybook deployment separate from your main app
- Optimized Builds: Only rebuilds when component-related files change
Deployment Metrics & Monitoring¶
All deployment workflows automatically collect and send metrics to Prometheus (Grafana Cloud) for monitoring and observability. This provides valuable insights into your deployment pipeline performance and health.
What Metrics Are Collected¶
During each deployment, the following metrics are automatically captured and sent to Prometheus:
Build & Deployment Metrics¶
- Build Success Rate: Percentage of successful vs failed deployments
- Deployment Frequency: How often deployments occur to each environment
- Build Duration: Time taken for builds and deployments to complete
- Workflow Status: Success/failure status of each deployment job
Test Coverage Metrics¶
- Overall Coverage: Combined test coverage percentage across all packages
- Coverage by Type: Statement, branch, function, and line coverage metrics
- Test Results: Number of tests run, passed, and failed
Environment Separation¶
All metrics are automatically tagged with:
- Service:
apporaihub - Environment:
stagingorproduction(auto-detected from branch) - Workflow Details: Workflow name, job name, run ID, commit SHA, and branch
How It Works¶
- Automatic Collection: After each deployment completes (success or failure), a
collect-metricsjob runs - Non-Intrusive: Metrics collection failures won't break your deployments
- Rich Context: Each metric includes comprehensive labels for filtering and alerting
- Real-time: Metrics appear in Grafana dashboards immediately after deployment
Configuration Required¶
To enable metrics collection, configure these GitHub repository settings:
Variables (Settings > Secrets and variables > Actions > Variables):
PROMETHEUS_URL: Your Prometheus remote write endpointPROMETHEUS_USER: Your Prometheus username
Secrets (Settings > Secrets and variables > Actions > Secrets):
PROMETHEUS_API_KEY: Your Prometheus API key
Runtime logs & dashboards (Grafana Loki)¶
Deployment metrics go to Prometheus (above); application runtime logs go to Grafana Loki. All packages (frontend-server, sana, aihub, the lambda functions) ship their warn + error logs to Loki through ONE mechanism: a per-event push transport in the common logger — no logs drain, no batched winston-loki. On Vercel the push is waitUntil-scheduled; in aiHub/lambdas logger.flushLogs() drains in-flight pushes before shutdown/freeze. info/debug are console-only (visible in Vercel's log UI / CloudWatch). Vercel Speed Insights / Web Analytics still ride a drain to /api/drains/grafana. The push and the analytics drain both reuse the existing LOKI_* variables (the drain also uses VERCEL_DRAIN_SECRET). For the label contract, the anti-recursion invariant, and the one-time Vercel drain cleanup, see GRAFANA_DASHBOARDS.md (§ "App / service logs → Loki (per-event in-process push)").