Advanced Patterns — Deploy Strategies & Release Automation
AdvancedProduction CI/CD patterns include semantic versioning automation, blue-green and canary deployments, automatic changelog generation, and deployment rollbacks triggered by health checks.
Overview
Basic pipelines build and push images. Production pipelines automate the full release lifecycle: semantic versioning (determine the next version from commit message conventions), changelog generation (from conventional commits), GitHub releases (create release with artifacts), deployment strategies (blue-green for zero-downtime switch, canary for gradual rollout), and automated rollback when health checks fail. These patterns reduce release ceremony from hours to minutes and give teams confidence to ship frequently.
Semantic Versioning & Conventional Commits
Conventional Commits is a specification for structured commit messages. Tools like semantic-release or release-please parse these messages to automatically determine the next semantic version and generate changelogs.
# Conventional Commit format:
# <type>(<scope>): <description>
# [optional body]
# [optional footer]
# Types:
# feat: new feature → bumps MINOR version (1.0.0 → 1.1.0)
# fix: bug fix → bumps PATCH version (1.0.0 → 1.0.1)
# docs: documentation only
# refactor: code change, no feature/fix
# test: adding tests
# chore: maintenance
# BREAKING CHANGE: footer → bumps MAJOR version (1.0.0 → 2.0.0)
# Examples:
# feat(auth): add OAuth2 login support
# fix(api): correct null pointer in user endpoint
# feat!: redesign API response format ↠! = breaking change
# feat(payments): add Stripe integration
#
# BREAKING CHANGE: The /users endpoint now returns camelCase fields
# .github/workflows/release.yml — automatic releases with release-please
name: Release Please
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: google-github-actions/release-please-action@v4
id: release
with:
release-type: node # parses package.json for version
token: ${{ secrets.GITHUB_TOKEN }}
# release-please opens a "Release PR" that:
# 1. Bumps version in package.json
# 2. Generates CHANGELOG.md from commits
# 3. When merged, creates a GitHub Release + git tagBlue-Green & Canary Deployments
Blue-green switches 100% of traffic instantly between two identical environments. Canary gradually shifts traffic, monitoring error rates before full rollout.
# Blue-Green Deployment (Kubernetes + GitHub Actions)
# Two identical Deployments (blue=current, green=new)
# Switch traffic by updating Service selector
# .github/workflows/blue-green.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Determine current active color
- name: Get active slot
id: slot
run: |
CURRENT=$(kubectl get service my-app -o jsonpath='{.spec.selector.slot}')
if [ "$CURRENT" = "blue" ]; then
echo "deploy_slot=green" >> $GITHUB_OUTPUT
echo "active_slot=blue" >> $GITHUB_OUTPUT
else
echo "deploy_slot=blue" >> $GITHUB_OUTPUT
echo "active_slot=green" >> $GITHUB_OUTPUT
fi
# Deploy to inactive slot (no traffic yet)
- name: Deploy to ${{ steps.slot.outputs.deploy_slot }}
run: |
kubectl set image deployment/my-app-${{ steps.slot.outputs.deploy_slot }} \
app=ghcr.io/org/my-app:${{ github.sha }}
kubectl rollout status deployment/my-app-${{ steps.slot.outputs.deploy_slot }}
# Smoke test the inactive slot (internal URL)
- name: Smoke test
run: curl -f http://my-app-${{ steps.slot.outputs.deploy_slot }}-internal/health
# Switch traffic: update Service selector
- name: Switch traffic to ${{ steps.slot.outputs.deploy_slot }}
run: |
kubectl patch service my-app -p \
'{"spec":{"selector":{"slot":"${{ steps.slot.outputs.deploy_slot }}"}}}'
# Keep old slot running (instant rollback by re-patching selector)
- name: Annotate for rollback
run: |
kubectl annotate deployment my-app \
last-active-slot=${{ steps.slot.outputs.active_slot }} --overwriteAutomated Rollback on Health Failure
The safest deployments include an automatic rollback step that triggers if health checks fail after deployment — no manual intervention needed.
# .github/workflows/deploy-with-rollback.yml
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
# Record current image for rollback
- name: Save current image
id: current
run: |
CURRENT_IMAGE=$(kubectl get deployment my-app \
-o jsonpath='{.spec.template.spec.containers[0].image}')
echo "image=$CURRENT_IMAGE" >> $GITHUB_OUTPUT
# Deploy new image
- name: Deploy
id: deploy
run: |
kubectl set image deployment/my-app app=ghcr.io/org/my-app:${{ github.sha }}
kubectl rollout status deployment/my-app --timeout=5m
# Health check — wait for service to stabilise
- name: Health check
id: health
run: |
for i in {1..12}; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://api.myapp.com/health)
if [ "$STATUS" = "200" ]; then
echo "Health check passed"
exit 0
fi
echo "Health check attempt $i/12 failed (status $STATUS), retrying in 10s..."
sleep 10
done
echo "Health checks failed after 2 minutes"
exit 1
# Automatic rollback on health failure
- name: Rollback on failure
if: failure() && steps.deploy.outcome == 'success'
run: |
echo "Deployment failed health checks — rolling back to ${{ steps.current.outputs.image }}"
kubectl set image deployment/my-app app=${{ steps.current.outputs.image }}
kubectl rollout status deployment/my-app --timeout=5m
echo "Rollback complete" >> $GITHUB_STEP_SUMMARY
# Notify on success or failure
- name: Notify Slack
if: always()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Deploy ${{ job.status }}: my-app:${{ github.sha }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}Key Points to Remember
- 1Conventional Commits enable automatic semantic versioning: feat → minor bump, fix → patch, BREAKING CHANGE → major.
- 2release-please opens "Release PRs" that auto-bump versions and generate changelogs.
- 3Blue-green: instant traffic switch between two live environments; rollback = switch back (seconds).
- 4Canary: gradual traffic shift with metric monitoring; safer but more complex to implement.
- 5Automatic rollback on health failure makes deployments safe without requiring 24/7 on-call monitoring.
- 6Always capture the current image/revision before deploying so rollback has a known good target.
Interview Questions
Sign in to ask AriaWhat is the difference between blue-green and canary deployment?
How do you implement automatic rollback in a CI/CD pipeline?
Ask Aria about Advanced Patterns — Deploy Strategies & Release Automation
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.