CI/CD Pipeline
This page explains the automated CI/CD pipeline for Vega — what runs automatically, what requires a manual trigger, and how to perform or roll back a deployment.
Overview
There are three GitHub Actions workflows in .github/workflows/:
| Workflow | File | Trigger | What it does |
|---|---|---|---|
| CI | ci.yml |
Every PR and every push to main |
Runs tests, validates Terraform, checks frontend build |
| Deploy Dev | deploy-dev.yml |
Auto after CI passes on main, or manual |
Builds images, scans, pushes to ECR, deploys to dev |
| Promote Prod | promote-prod.yml |
Manual only (requires a dev-validated SHA) | Promotes an immutable image tag from dev ECR to prod |
The normal flow is:
Open PR → CI runs → merge to main → CI runs again → Deploy Dev auto-triggers → dev is updated
↓
(validate dev manually)
↓
Trigger Promote Prod with the SHA
↓
prod is updated
Workflow: CI
Runs on: every pull request and every push to main.
| Job | What it checks |
|---|---|
backend-tests |
Runs pytest tests with all Python dependencies |
frontend-build |
Runs npm ci && npm run build to verify the frontend compiles |
terraform-validate |
Checks terraform fmt, init, and validate for both dev and prod environments |
shell-syntax |
Checks bash -n syntax on all scripts/aws/*.sh files |
If any job fails, the PR is blocked and Deploy Dev will not trigger.
Workflow: Deploy Dev
Runs automatically after CI succeeds on main. Can also be triggered manually from the GitHub Actions tab.
The workflow assumes the GitHub Actions deploy role (AWS_DEV_DEPLOY_ROLE_ARN) via OIDC — no long-lived AWS credentials are stored in GitHub.
Steps in order
- Checkout — checks out the commit with submodules (including
vega-core/) usingVEGA_CORE_CHECKOUT_TOKEN - Resolve release SHA — captures the 12-character Git SHA that will become the immutable image tag
- Configure AWS credentials — assumes the
vega-dev-github-actions-deployIAM role via GitHub OIDC - Build service images — runs
scripts/aws/build-images.sh dev <sha>, which builds five Docker images:vega-api,vega-worker,vega-maintenance,vega-llm-proxy,vega-core-runner - Scan images with Trivy — fails the workflow if any image has an unfixed HIGH or CRITICAL vulnerability
- Generate SBOMs — generates a CycloneDX SBOM for each image with Syft and uploads them as artifacts
- Push images to ECR — runs
scripts/aws/push-images.sh dev <sha>, which pushes each image with both the immutable SHA tag and thedev-currentmutable tag - Terraform plan dev — runs
scripts/aws/terraform-plan.sh dev - Reject unexpected destroys — fails the workflow if the plan includes any destructive changes on resource types that shouldn't be destroyed (excluding ECS task definitions, which rotate normally)
- Upload Terraform plan — saves the plan as an artifact for review
- Terraform apply dev — runs
scripts/aws/terraform-apply.sh dev - Run dev migrations — runs
scripts/aws/run-migrations.sh dev <sha>, which launches thevega-maintenanceECS task to apply pending Alembic migrations - Deploy dev ECS services — runs
scripts/aws/deploy-services.sh dev <sha>, which force-deploysvega-api,vega-worker, andvega-llm-proxyand waits for them to stabilize - Smoke test dev — runs
scripts/aws/smoke-test.sh devto verify the API health endpoint returns 200
Frontend is not deployed automatically
The CI/CD pipeline does not currently upload the frontend to S3. Frontend deployments are manual. See Deploy a frontend change.
Workflow: Promote Prod
Runs only when manually triggered from the GitHub Actions tab. It requires you to input:
image_sha— the immutable 12-character Git SHA that was already built, scanned, pushed to ECR, and smoked in dev. This prevents building new code directly against prod.deploy_worker_path— set totrueonly when prod worker/LLM proxy credentials are populated and scan execution has been approved.
The workflow assumes the vega-prod-github-actions-deploy IAM role. It runs in the prod GitHub Environment, which can be configured with required reviewers to add a manual approval gate before the workflow proceeds.
Steps in order
- Checkout — checks out current
mainwith submodules - Resolve and validate release SHA — rejects
dev-currentorprod-currentas input (only accepts an immutable SHA) - Configure AWS credentials — assumes the prod deploy role via OIDC
- Verify image tags exist in ECR — confirms the provided SHA tag exists in ECR for all five image repositories before proceeding
- Terraform plan prod — generates a prod plan
- Reject unexpected prod destroys — same guard as dev, but applied to prod
- Upload prod Terraform plan — saves the plan for audit
- Terraform apply prod — applies the plan with the
--confirm-prodsafety flag - Run prod migrations — applies pending migrations against the prod database
- Deploy prod ECS services — force-deploys prod services and waits for stability
- Smoke test prod — verifies the prod API health endpoint returns 200
Triggering a manual dev deploy
To re-deploy dev without merging new code (for example, after updating a secret or Terraform configuration):
- Go to Actions → Deploy Dev in GitHub
- Click Run workflow on the
mainbranch - The workflow runs exactly the same steps as the automatic trigger
Promoting a SHA to production
-
Find the SHA to promote. It must already have passed the full Deploy Dev run:
Or look at the "Resolve release SHA" step output in a successful Deploy Dev run in GitHub Actions.# The SHA is the 12-character prefix of the commit that triggered Deploy Dev git log --oneline -10 -
Go to Actions → Promote Prod in GitHub
-
Click Run workflow and enter:
image_sha: the 12-character SHA (e.g.,abc123def456)deploy_worker_path:falseunless explicitly enabling scan execution in prod
-
If the
prodGitHub Environment has required reviewers configured, approve the deployment when prompted. -
Monitor the run. The workflow uploads the Terraform plan as an artifact — download and review it before the apply step if the plan includes unexpected changes.
Rollback procedure
Because images are tagged with immutable Git SHAs, rolling back means re-promoting the last known-good SHA.
Backend rollback (API, worker, LLM proxy, runner):
- Find the previous good SHA from a successful Deploy Dev or Promote Prod run
- Trigger Promote Prod with that SHA
This re-applies the Terraform task definitions pointing to the old images and force-deploys ECS services to pull them.
Manual rollback (dev only):
PREV_SHA=<previous-12-char-sha>
# Update Terraform variables to point to the old SHA
TF_VAR_api_image_tag=$PREV_SHA \
TF_VAR_runner_image_tag=$PREV_SHA \
TF_VAR_llm_proxy_image_tag=$PREV_SHA \
scripts/aws/terraform-apply.sh dev
scripts/aws/deploy-services.sh dev "$PREV_SHA"
scripts/aws/smoke-test.sh dev
Frontend rollback:
The previous frontend bundle is not automatically retained. To roll back the frontend, check out the previous commit, rebuild with the same Vite environment variables, and re-upload to S3. See Deploy a frontend change.
Database migrations are not automatically reversed
Rolling back application code does not undo database migrations. If the previous code cannot run against the current schema, you must apply a down-migration or a corrective migration manually. Design migrations to be backward-compatible with the previous application version to make rollbacks safe.
Required GitHub configuration
The workflows require the following to be set on the repository:
| Type | Name | Value |
|---|---|---|
| Repository variable | AWS_REGION |
us-west-1 |
| Repository variable | AWS_DEV_DEPLOY_ROLE_ARN |
ARN of the vega-dev-github-actions-deploy IAM role (from terraform output github_actions_dev_role_arn) |
| Repository variable | AWS_PROD_DEPLOY_ROLE_ARN |
ARN of the vega-prod-github-actions-deploy IAM role (from terraform output github_actions_prod_role_arn) |
| Repository secret | VEGA_CORE_CHECKOUT_TOKEN |
Fine-grained PAT with read access to vega-backend and vega-core (for private submodule checkout) |
| GitHub Environment | dev |
No required reviewers needed |
| GitHub Environment | prod |
Add required reviewers for a manual approval gate |
The deploy roles are defined in Terraform:
- infra/terraform/envs/dev/ci_role.tf
- infra/terraform/envs/prod/ci_role.tf