Not every push should ship
Pull requests should be tested but never deployed; a version tag like v1.2.0 should become a release. Environments (staging, production) add protection rules and their own secrets, and concurrency stops two deploys racing each other.
Gated deploys
name: Release
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]
concurrency:
group: deploy-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "testing ${{ github.ref_name }}"
staging:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: staging
steps:
- run: echo "deploying main to staging"
production:
needs: test
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
environment:
name: production
url: https://cafe.example.com
steps:
- run: echo "releasing ${{ github.ref_name }} to production"