# GitLab CI/CD: Multi-Stage Deployment

Deploy to staging, test, then promote to production with approval.

```yaml title=".gitlab-ci.yml"
image: node:20

stages:
  - deploy-staging
  - test
  - deploy-production

deploy-staging:
  stage: deploy-staging
  script:
    - npm install
    - npx zuplo deploy --api-key "$ZUPLO_API_KEY" --environment staging 2>&1 |
      tee ./DEPLOYMENT_STDOUT
    - echo "STAGING_URL=$(grep -oP 'Deployed to \K(https://[^ ]+)'
      ./DEPLOYMENT_STDOUT)" >> staging.env
  artifacts:
    reports:
      dotenv: staging.env
  only:
    - main

test-staging:
  stage: test
  needs:
    - deploy-staging
  script:
    - npm install
    - npx zuplo test --endpoint "$STAGING_URL"
  only:
    - main

deploy-production:
  stage: deploy-production
  needs:
    - test-staging
  script:
    - npm install
    - npx zuplo deploy --api-key "$ZUPLO_API_KEY" --environment production
  only:
    - main
  when: manual
  environment:
    name: production
```

## Setting Up Approval

The `when: manual` setting requires someone to click "Play" in the GitLab UI to
trigger production deployment.

For more control, use
[Protected Environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html):

1. Go to **Settings** > **CI/CD** > **Protected environments**
2. Add `production` as a protected environment
3. Specify which users or groups can deploy
