Reuse, release, and deploy

Use protected environments and rollback

Attach approvals, scoped secrets, deployment history, verification, and a tested rollback to production.

An environment in GitHub Actions is more than a label. It is a gate: who may deploy, which secrets appear, and what deployment history GitHub records.

Production deserves required reviewers, scoped secrets, post-deploy checks, and a rehearsed rollback.

Without environment protection, any workflow with deploy credentials can push to production on every push to main. One mistaken merge or stolen token is enough.

GitHub records deployment history per environment. That timeline helps during incidents: you can see which commit reached production and when.

Gate production with environment protection

jobs:
  deploy:
    environment:
      name: production
      url: https://flaviocopes.com
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: site-${{ github.sha }}
          path: dist/
      - run: ./scripts/deploy.sh dist/ production
      - run: curl -fsS https://flaviocopes.com/health

In repository settings, add required reviewers on the production environment. The job pauses until someone approves.

Only production-scoped secrets attach to that environment.

Verify from outside the deploy script

A green deploy step only means your script exited zero. Hit a health URL or run a smoke test against the live site:

- name: Smoke test
  run: |
    curl -fsS https://flaviocopes.com/health | grep ok

If the check fails, fail the job before you call the release done.

Keep the previous artifact for rollback

Store the last good artifact name or digest in your runbook. Rolling back should redeploy a known tarball, not rebuild from main at an old commit unless you must.

Rehearse on staging: deploy a broken health response, confirm alerts fire, roll back to the previous artifact, confirm health returns.

Document who approves production and what “rollback” means for your stack. Redeploy last artifact, DNS swap, or database migration reversal each need different steps.

Try this on your own project: add one required reviewer and one smoke test step, then run a full staging deploy drill.

Lesson completed