A well-designed CI/CD pipeline is the backbone of modern software delivery. This guide covers how to build pipelines that are fast, reliable, and safe.
Pipeline Design Principles
- Fail fast: Run quick checks first
- Parallelize: Run independent jobs concurrently
- Cache aggressively: Don't rebuild what hasn't changed
- Keep it reproducible: Same input = same output
Example: GitHub Actions Pipeline
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
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
test:
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: \${{ matrix.node }}
cache: 'npm'
- run: npm ci
- run: npm test
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build
path: dist/
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/download-artifact@v4
with:
name: build
- name: Deploy to production
run: ./scripts/deploy.sh
Testing Strategies
The Testing Pyramid
/\\
/ \\ E2E Tests (few)
/----\\
/ \\ Integration Tests (some)
/--------\\
/ \\ Unit Tests (many)
/--------------\\
Parallel Test Execution
# Split tests across multiple runners
test:
parallel: 4
script:
- npm run test -- --shard=\$CI_NODE_INDEX/\$CI_NODE_TOTAL
Deployment Strategies
Blue-Green Deployment
1. Deploy to "green" environment
2. Run smoke tests
3. Switch load balancer to "green"
4. Keep "blue" as rollback target
Canary Releases
1. Deploy to canary (1-5% of traffic)
2. Monitor error rates and latency
3. Gradually increase traffic
4. Full rollout if metrics are healthy
Feature Flags
// Deploy code, control visibility with flags
if (featureFlags.isEnabled('new-checkout')) {
return <NewCheckout />;
}
return <LegacyCheckout />;
Rollback Mechanisms
Always have a rollback plan:
# Kubernetes rollback
kubectl rollout undo deployment/my-app
# Docker rollback to previous tag
docker tag my-app:previous my-app:latest
docker push my-app:latest
# Database migrations
php artisan migrate:rollback --step=1
Monitoring in Production
After deployment, monitor these metrics:
- Error rate: Should not spike after deploy
- Latency: p50, p95, p99 response times
- Throughput: Requests per second
- Resource usage: CPU, memory, connections
# Prometheus alert for deploy health
- alert: HighErrorRateAfterDeploy
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) > 0.01
for: 2m
annotations:
summary: "Error rate above 1% after deployment"
A good CI/CD pipeline gives you confidence to deploy frequently and safely. Invest in it—your future self will thank you.
Comments (0)
Leave a Comment
No comments yet. Be the first to share your thoughts!