๐ŸŒ Detecting your locationโ€ฆ
๐Ÿ“ข Advertisement โ€” Configure AdSense in Appearance โ†’ Customize โ†’ AdSense Settings

CI/CD Complete Guide 2026: GitHub Actions, Canary Deploys and Rollback

โฑ๏ธ5 min read  ยท  956 words

Modern CI/CD in 2026 goes beyond basic test-and-deploy. Feature flags, blue-green deployments, canary releases, GitOps with automatic rollback, and security scanning in the pipeline are now standard. This guide covers building a production-grade CI/CD pipeline from scratch.

The Modern CI/CD Pipeline

Stages:
1. Trigger (push, PR, schedule)
2. Fast checks (lint, type, security scan) < 2 min
3. Build (Docker image) < 5 min
4. Test (unit + integration) < 10 min
5. Publish (push to registry)
6. Deploy to staging
7. E2E tests on staging
8. Deploy to production (canary or blue-green)
9. Monitor + alert

Principles:
- Fail fast โ€” security/lint first
- Parallel where possible
- Cache aggressively
- Artifacts immutable (same image devโ†’prod)
- Rollback automated on failed health checks

GitHub Actions โ€” Complete Workflow

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  # โ”€โ”€ FAST CHECKS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  fast-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip

      - name: Install tools
        run: pip install ruff mypy

      - name: Lint
        run: ruff check .

      - name: Format check
        run: ruff format --check .

      - name: Type check
        run: mypy app/ --ignore-missing-imports

      - name: Security scan
        uses: pypa/gh-action-pip-audit@v1.1.0
        with:
          inputs: requirements.txt

  # โ”€โ”€ TESTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  test:
    needs: fast-checks
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_DB: test_db
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
        ports:
          - 5432:5432
        options: --health-cmd pg_isready

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
          cache: pip

      - name: Install dependencies
        run: pip install -r requirements.txt -r requirements-dev.txt

      - name: Run tests
        env:
          DATABASE_URL: postgresql://test:test@localhost:5432/test_db
        run: pytest --cov=app --cov-fail-under=80 --cov-report=xml -q

      - name: Upload coverage
        uses: codecov/codecov-action@v4

  # โ”€โ”€ BUILD IMAGE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    outputs:
      image: ${{ steps.meta.outputs.tags }}
      digest: ${{ steps.build.outputs.digest }}

    steps:
      - uses: actions/checkout@v4

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Docker metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=sha,prefix=,suffix=,format=short
            type=raw,value=latest

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push
        id: build
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  # โ”€โ”€ DEPLOY STAGING โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging

    steps:
      - uses: actions/checkout@v4

      - name: Deploy to staging
        run: |
          helm upgrade --install myapp ./charts/myapp             --namespace staging             --set image.tag=${{ github.sha }}             --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}             -f helm/values.staging.yaml             --wait --timeout 5m --atomic

  # โ”€โ”€ E2E TESTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  e2e-staging:
    needs: deploy-staging
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Install Playwright
        run: npm ci && npx playwright install chromium

      - name: Run E2E tests
        run: npx playwright test
        env:
          BASE_URL: https://staging.myapp.com

  # โ”€โ”€ DEPLOY PRODUCTION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
  deploy-production:
    needs: e2e-staging
    runs-on: ubuntu-latest
    environment: production  # requires manual approval

    steps:
      - uses: actions/checkout@v4

      - name: Deploy canary (10%)
        run: |
          helm upgrade --install myapp-canary ./charts/myapp             --namespace production             --set image.tag=${{ github.sha }}             --set replicaCount=1             -f helm/values.prod.yaml

      - name: Wait and check canary health
        run: |
          sleep 300  # 5 min canary window
          # Check error rate via Prometheus
          ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query?query=rate(http_requests_total{status=~'5..'}[5m])" | jq '.data.result[0].value[1]')
          if (( $(echo "$ERROR_RATE > 0.01" | bc -l) )); then
            echo "Canary failed with error rate $ERROR_RATE"
            helm rollback myapp-canary
            exit 1
          fi

      - name: Full rollout
        run: |
          helm upgrade --install myapp ./charts/myapp             --namespace production             --set image.tag=${{ github.sha }}             -f helm/values.prod.yaml             --wait --atomic

Feature Flags with Unleash

from unleash import UnleashClient

client = UnleashClient(
    url="https://unleash.mycompany.com",
    app_name="myapp",
    custom_headers={"Authorization": "*:production.SECRET"},
)
client.initialize_client()

# Check feature flag
if client.is_enabled("new-checkout-flow"):
    return new_checkout_flow(cart)
else:
    return legacy_checkout(cart)

# Feature flag with user context (gradual rollout to specific users)
context = {"userId": str(user.id), "properties": {"plan": user.plan}}
if client.is_enabled("beta-feature", context=context):
    return beta_feature()

Automated Rollback

# Auto-rollback script (run in monitoring job)
#!/bin/bash
ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query"   --data-urlencode 'query=rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])'   | jq -r '.data.result[0].value[1] // "0"')

P99_LATENCY=$(curl -s "http://prometheus:9090/api/v1/query"   --data-urlencode 'query=histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))'   | jq -r '.data.result[0].value[1] // "0"')

ERROR_THRESHOLD="0.05"   # 5% error rate
LATENCY_THRESHOLD="2.0"  # 2 second P99

if (( $(echo "$ERROR_RATE > $ERROR_THRESHOLD" | bc -l) )) ||    (( $(echo "$P99_LATENCY > $LATENCY_THRESHOLD" | bc -l) )); then
  echo "SLO violation detected! Rolling back..."
  helm rollback myapp -n production
  # Send alert
  curl -X POST "$SLACK_WEBHOOK"     -H "Content-Type: application/json"     -d "{"text": "ALERT: Auto-rollback triggered! Error rate: $ERROR_RATE, P99: $P99_LATENCY"}"
fi

Production CI/CD in 2026 is about reliability and speed. Fast feedback loops (lint/security in 2 minutes), parallel testing, immutable Docker artifacts, canary deployments with automated rollback, and feature flags for safe releases. The investment in a solid pipeline pays dividends every deployment โ€” confident, frequent releases with instant rollback capability.

โœ๏ธ Leave a Comment

Your email address will not be published. Required fields are marked *

๐ŸŒ Read in:๐Ÿ‡ฌ๐Ÿ‡ง English๐Ÿ‡ฉ๐Ÿ‡ช Deutsch๐Ÿ‡ง๐Ÿ‡ท Portuguรชs๐Ÿ‡ธ๐Ÿ‡ฆ ุงู„ุนุฑุจูŠุฉ๐Ÿ‡ฎ๐Ÿ‡ณ เคนเคฟเคจเฅเคฆเฅ€๐Ÿ‡ง๐Ÿ‡ฉ เฆฌเฆพเฆ‚เฆฒเฆพ