Answer
GitHub Actions Environments
Environments represent deployment targets — staging, qa, production — with their own secrets, variables, and protection rules.
Creating an Environment
CODE
Repository → Settings → Environments → New environment
Configure:
- ✓Name:
production - ✓Protection rules:
- ✓Required reviewers: 2 people must approve
- ✓Wait timer: 5 minutes before deploy starts
- ✓Deployment branch rule: only
mainbranch
- ✓Secrets:
PROD_DB_URL,PROD_API_KEY(scoped to this env only)
Using an Environment in a Workflow
YAML
name: Deploy Pipeline
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging # ← links to staging environment
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: ./deploy.sh staging
env:
DB_URL: ${{ secrets.DB_URL }} # staging secret
API_KEY: ${{ secrets.API_KEY }} # staging secret
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production # ← links to production environment
url: https://automateqa.online # shown in GitHub UI as deployment URL
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: ./deploy.sh production
env:
DB_URL: ${{ secrets.DB_URL }} # production secret (different values!)
API_KEY: ${{ secrets.API_KEY }}
Protection Rules in Action
CODE
Flow with required reviewer:
1. Workflow runs → reaches deploy-production job
2. GitHub PAUSES the job ← waiting for approval
3. Reviewers get notified via email/GitHub notification
4. Reviewer clicks "Approve" in GitHub UI
5. Job resumes and deploys to production
Wait Timer
CODE
Settings → Environment → Wait timer: 10 minutes
→ After all checks pass, GitHub waits 10 minutes
→ Then auto-starts the deployment
→ Use case: gives team time to notice and cancel if needed
Branch Protection — Only Deploy From Specific Branches
CODE
Settings → Environment → Deployment branch and tag rules
→ Selected branches: main
→ Only workflows running on 'main' branch can deploy here
→ PRs cannot accidentally trigger production deployments
Staged Deployment Pattern
YAML
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: mvn test
deploy-staging:
needs: test
runs-on: ubuntu-latest
environment: staging # no protection — auto-deploys
steps:
- run: ./deploy.sh staging
integration-tests:
needs: deploy-staging
runs-on: ubuntu-latest
steps:
- run: mvn test -Dsuite=integration -Denv=staging
deploy-production:
needs: integration-tests
runs-on: ubuntu-latest
environment: production # REQUIRES APPROVAL ← protected
steps:
- run: ./deploy.sh production
Environment Variables (Not Secrets)
CODE
Settings → Environment → Variables (non-sensitive config)
Name: BASE_URL Value: https://staging.automateqa.online
YAML
steps:
- run: mvn test -DbaseUrl=${{ vars.BASE_URL }}
