Environments and Promotion

This tutorial explains how to configure environments in GAIA, how the promotion chain moves code from development to production, how to manage per-environment secrets, and what happens when you run /gaia-deploy.

Why environments matter

Environments are isolated copies of your application at different stages of readiness. A typical setup has three: dev (for integration testing), staging (for pre-production validation), and production (for end users). Each environment can have its own database, secrets, and infrastructure configuration.

Without explicit environment configuration, GAIA cannot deploy your application, run post-deploy smoke tests, or enforce promotion gates. The environments section in project-config.yaml makes your deployment pipeline explicit and repeatable.

The environments section

Each environment is defined as a named entry under environments:

# .gaia/config/project-config.yaml
environments:
  dev:
    url: https://dev.example.com
    auto_deploy: true
    requires_approval: false
  staging:
    url: https://staging.example.com
    auto_deploy: true
    requires_approval: false
  production:
    url: https://example.com
    auto_deploy: false
    requires_approval: true

auto_deploy controls whether merges to the environment's branch trigger an automatic deployment. requires_approval controls whether a human must approve the deployment before it proceeds.

Edit this section with /gaia-config-env, which preserves comments and formatting in your YAML files.

Three-environment chain (dev, staging, production)

This is the most common setup for teams of 5 or more developers. Code flows through three stages:

  1. Dev: Feature branches are merged here. Auto-deploy is on. Integration tests run against a shared database. Failures here are expected and cheap.
  2. Staging: Code that passes dev is promoted to staging. This environment mirrors production as closely as possible -- same infrastructure, same data shape, same secrets format (with test values). QA and stakeholder review happens here.
  3. Production: Code that passes staging is promoted to production. Auto-deploy is off. A human approves the deployment after reviewing the deploy checklist.
# .gaia/config/project-config.yaml
ci_cd:
  promotion_chain:
    - dev
    - staging
    - production

Branch mapping

The promotion chain implies branch mapping: devdevelop branch, stagingstaging branch, productionmain branch. You can override these mappings in the environment configuration if your branch names differ.

Two-environment chain (staging, production)

For smaller teams (2--5 developers), a two-stage chain is simpler and sufficient. Feature branches merge directly to staging, then promote to production.

# .gaia/config/project-config.yaml
ci_cd:
  promotion_chain:
    - staging
    - production

environments:
  staging:
    url: https://staging.example.com
    auto_deploy: true
    requires_approval: false
  production:
    url: https://example.com
    auto_deploy: false
    requires_approval: true

The trade-off: without a dev environment, staging is where integration issues surface. If you have flaky integration tests or external dependencies that fail intermittently, staging becomes noisy. In that case, add a dev environment.

Per-environment secrets

Each environment needs its own set of secrets (API keys, database credentials, third-party tokens). GAIA does not store secrets. It expects your CI platform to provide them.

GitHub Actions

Use GitHub Environments to scope secrets:

  • Create environments named dev, staging, production in your repository settings.
  • Add secrets to each environment. A DATABASE_URL secret in the staging environment is only available to jobs that reference environment: staging.
  • Add environment protection rules (required reviewers, wait timers) to the production environment.

GitLab CI

Use CI/CD variable scopes:

  • Define variables with the "Environment scope" set to dev, staging, or production.
  • Use protected variables for production secrets.

Never commit secrets

Do not put secrets in project-config.yaml, .env files, or any file that is committed to version control. Use your CI platform's secret management or an external secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.).

What /gaia-deploy does

/gaia-deploy orchestrates a deployment through a fixed sequence:

  1. Pre-deploy gate: Runs a composite gate check to verify all prerequisites are met (tests passed, reviews approved, checklist complete).
  2. Deploy: Invokes the configured deploy adapter (e.g., Vercel, AWS, GCP, custom script) for the target environment.
  3. Health check: Waits for the deployment to be healthy (HTTP 200 on the environment URL).
  4. Post-deploy smoke: Runs a smoke test suite against the deployed environment.
  5. Verdict: Reports PASSED or FAILED based on the smoke test results.

The deploy is sequential and transparent. There is no auto-retry and no auto-rollback. If the deployment fails, you investigate and decide whether to re-deploy or roll back.

Pre-deploy gates

Before deploying, GAIA checks that all required gates have passed. Use /gaia-deploy-checklist to generate a pre-deployment verification checklist:

/gaia-deploy-checklist

The checklist includes items like:

  • All CI checks passed on the deployment branch.
  • Required code reviews are approved.
  • No open blockers in the current sprint.
  • Database migrations are reviewed and tested.
  • Rollback plan is documented.

For the enterprise CI preset, the checklist is a hard gate -- deployment cannot proceed until all items are checked.

Post-deploy smoke tests

After a deployment, GAIA runs a smoke test to verify the deployment is healthy. Smoke tests are fast (under 60 seconds) and test only critical paths -- login, main page load, API health endpoint.

Configure smoke tests in the test_execution section:

# .gaia/config/project-config.yaml
test_execution:
  smoke:
    command: npm run test:smoke
    timeout_seconds: 60

The /gaia-post-deploy command runs after deployment and includes the smoke test, plus any additional post-deployment checks you configure (performance baselines, error rate monitoring).

Rollback planning

Every deployment should have a rollback plan. Use /gaia-rollback-plan to generate one before deploying.

A rollback plan answers:

  • What triggers a rollback? (e.g., error rate above 1%, P95 latency above 500ms, smoke test failure)
  • How do you roll back? (e.g., revert the merge, redeploy the previous version, toggle a feature flag)
  • Who decides? (e.g., on-call engineer, team lead, automated based on metrics)
  • What about database changes? (e.g., migrations are backward-compatible, or a down migration is tested)

Backward-compatible migrations

The safest rollback strategy is to ensure every database migration is backward-compatible. The new code works with the new schema, and the old code also works with the new schema. This means you can roll back code without rolling back the database.

What to read next