正在加载,请稍候…

CI/CD Pipeline Best Practices: Fast Feedback and Safe Deployments

Build effective CI/CD pipelines. Learn pipeline stages, testing strategies, deployment strategies, rollback mechanisms, and measuring pipeline performance.

CI/CD Pipeline Best Practices

Pipeline Stages

Code Push
    |
    v
[1] Build & Lint (< 2 min)
    - Compile TypeScript
    - Run ESLint
    - Check formatting
    |
    v
[2] Unit Tests (< 5 min)
    - Run jest unit tests
    - Check coverage threshold
    |
    v
[3] Integration Tests (< 10 min)
    - Spin up test DB/Redis
    - Run integration tests
    |
    v
[4] Build Docker Image (< 5 min)
    - Multi-stage build
    - Push to registry
    |
    v
[5] Deploy to Staging (< 3 min)
    |
    v
[6] E2E Tests (< 15 min)
    - Playwright tests against staging
    |
    v
[7] Deploy to Production (manual approval)

GitHub Actions Pipeline

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

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

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: myorg/api

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 20
        cache: npm

    - run: npm ci
    - run: npm run lint
    - run: npm run type-check
    - run: npm run test:unit -- --coverage

    - uses: actions/upload-artifact@v4
      with:
        name: coverage
        path: coverage/

  integration-test:
    needs: quality
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: test
        options: >-
          --health-cmd pg_isready
          --health-interval 5s
          --health-timeout 5s
          --health-retries 5
      redis:
        image: redis:7
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 5s

    steps:
    - uses: actions/checkout@v4
    - run: npm ci
    - run: npm run test:integration
      env:
        DATABASE_URL: postgresql://postgres:test@localhost:5432/test
        REDIS_URL: redis://localhost:6379

  build:
    needs: integration-test
    runs-on: ubuntu-latest
    outputs:
      image: ${{ steps.meta.outputs.tags }}
    steps:
    - uses: actions/checkout@v4

    - uses: docker/metadata-action@v5
      id: meta
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=sha,prefix=sha-
          type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}

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

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging
    steps:
    - name: Deploy to staging
      run: |
        kubectl set image deployment/api api=${{ needs.build.outputs.image }}
        kubectl rollout status deployment/api --timeout=120s

  e2e:
    needs: deploy-staging
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - run: npm ci
    - run: npx playwright install --with-deps
    - run: npx playwright test
      env:
        BASE_URL: https://staging.myapp.com

  deploy-production:
    needs: e2e
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://myapp.com
    steps:
    - name: Deploy to production
      run: |
        kubectl set image deployment/api api=${{ needs.build.outputs.image }} -n production
        kubectl rollout status deployment/api -n production --timeout=300s

Deployment Strategies

# Rolling update (default in Kubernetes)
kubectl set image deployment/api api=myimage:v2
kubectl rollout status deployment/api

# Rollback if issues
kubectl rollout undo deployment/api

# Canary deployment
kubectl apply -f canary-deployment.yaml  # 10% of pods run new version
# Monitor metrics...
kubectl scale deployment api-canary --replicas=0  # Rollback
# OR
kubectl scale deployment api-canary --replicas=10 # Full rollout

# Blue-Green deployment
kubectl patch service api -p '{"spec":{"selector":{"version":"green"}}}'

Measuring Pipeline Effectiveness

DORA Metrics:
  Deployment Frequency: How often you deploy to production
    Elite: Multiple times/day
    
  Lead Time for Changes: Code commit -> production
    Elite: < 1 hour

  Change Failure Rate: % of deployments causing incidents
    Elite: 0-15%

  Mean Time to Restore (MTTR): Time to recover from failures
    Elite: < 1 hour

A fast, reliable CI/CD pipeline is the foundation of high-performing engineering teams.