CI/CD Pipeline Design: From GitHub Actions to Production Deploys
CI/CD Pipeline Design: From GitHub Actions to Production#
A good CI/CD pipeline is the difference between deploying with confidence and deploying with fear. This guide covers the patterns that work for real teams — from single-repo apps to complex microservices.
The Pipeline Stages#
Every CI/CD pipeline has the same core stages:
Push → Build → Test → Security Scan → Deploy Staging → Deploy Production
Each stage is a gate. If any stage fails, the pipeline stops.
Pipeline Patterns#
1. Simple App Pipeline#
# .github/workflows/ci.yml
name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npm run lint
- run: npm run test
- run: npm run build
deploy:
needs: build-and-test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- run: npx vercel --prod --token=${{ secrets.VERCEL_TOKEN }}
2. Microservices Pipeline#
Each service has its own pipeline, triggered by path changes:
on:
push:
paths:
- 'services/api/**'
- '.github/workflows/api.yml'
jobs:
api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cd services/api && npm ci && npm test
- uses: docker/build-push-action@v5
with:
context: services/api
push: true
tags: registry/api:${{ github.sha }}
- run: kubectl set image deployment/api api=registry/api:${{ github.sha }}
Key: Only build/deploy what changed. Path filters prevent unnecessary builds.
3. Monorepo Pipeline#
Use a build system that understands the dependency graph:
jobs:
detect-changes:
outputs:
api: ${{ steps.changes.outputs.api }}
web: ${{ steps.changes.outputs.web }}
shared: ${{ steps.changes.outputs.shared }}
steps:
- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
api: ['packages/api/**', 'packages/shared/**']
web: ['packages/web/**', 'packages/shared/**']
shared: ['packages/shared/**']
build-api:
needs: detect-changes
if: needs.detect-changes.outputs.api == 'true'
# ... build api
build-web:
needs: detect-changes
if: needs.detect-changes.outputs.web == 'true'
# ... build web
Tools: Turborepo, Nx, Bazel for intelligent caching and task orchestration.
4. GitOps (ArgoCD)#
Push manifests to Git, ArgoCD syncs to cluster:
Developer → Push code → CI builds image → Push image tag to manifests repo
ArgoCD watches manifests repo → detects change → syncs to Kubernetes
# manifests/api/deployment.yaml (updated by CI)
spec:
containers:
- name: api
image: registry/api:abc123 # CI updates this SHA
Benefits: Git is the source of truth. Rollback = git revert. Audit trail = git log.
Testing Strategy#
| Test Type | When | Speed | Confidence |
|---|---|---|---|
| Lint | Every push | < 30s | Catches style issues |
| Unit tests | Every push | < 2min | Core logic |
| Integration tests | Every push | < 5min | Service interactions |
| E2E tests | PR + main | < 15min | User flows |
| Load tests | Weekly/release | < 30min | Performance |
| Security scan | Every push | < 5min | Vulnerabilities |
Don't run everything on every push. Fast tests on every commit, slow tests on PRs and main.
Deployment Strategies#
Blue-Green#
Two identical environments. Switch traffic instantly:
Blue (current) ← 100% traffic
Green (new) ← 0% traffic
Deploy to Green → test → switch:
Blue ← 0% traffic
Green ← 100% traffic
Rollback? Switch back to Blue instantly.
Canary#
Gradually shift traffic to the new version:
v1 ← 95% traffic
v2 ← 5% traffic (canary)
Monitor errors/latency for 30min...
v1 ← 50% traffic
v2 ← 50% traffic
All good? v2 ← 100% traffic
Rolling Update (Kubernetes default)#
Replace pods one at a time:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
Feature Flags#
Deploy code to production but hide behind a flag:
if (featureFlags.isEnabled("new-checkout", user)) {
return <NewCheckout />;
}
return <OldCheckout />;
Tools: LaunchDarkly, Unleash, Flagsmith, PostHog
CI/CD Tools Compared#
| Tool | Type | Best For |
|---|---|---|
| GitHub Actions | Cloud CI | GitHub repos, most teams |
| GitLab CI | Cloud/Self-hosted | GitLab users, self-hosted |
| CircleCI | Cloud CI | Complex workflows, Docker |
| Jenkins | Self-hosted | Enterprise, custom plugins |
| ArgoCD | GitOps | Kubernetes deployments |
| Flux | GitOps | K8s, Helm charts |
| Buildkite | Hybrid | Self-hosted agents, cloud UI |
| Dagger | Programmable CI | CI pipelines as code (Go/Python/TS) |
Security in the Pipeline#
Code Push → SAST (static analysis) → SCA (dependency scan) → Build
→ Container scan (Trivy) → DAST (running app) → Deploy
| Scan Type | What | Tools |
|---|---|---|
| SAST | Code vulnerabilities | Semgrep, CodeQL, SonarQube |
| SCA | Dependency vulnerabilities | Snyk, Dependabot, Socket |
| Container | Image vulnerabilities | Trivy, Grype, Scout |
| Secrets | Leaked credentials | GitLeaks, TruffleHog |
| DAST | Running app vulnerabilities | OWASP ZAP, Burp Suite |
Pipeline Best Practices#
- Fast feedback — lint + unit tests < 2 minutes
- Cache aggressively — node_modules, Docker layers, build artifacts
- Immutable artifacts — build once, deploy same artifact to staging + prod
- Environment parity — staging mirrors production
- Secrets in vault — never in code, use GitHub Secrets or Vault
- Rollback plan — every deploy should be reversible in < 5 minutes
Summary#
| Pattern | When |
|---|---|
| Simple pipeline | Single app, small team |
| Path-filtered | Microservices, monorepo |
| GitOps (ArgoCD) | Kubernetes, audit requirements |
| Blue-green | Zero-downtime, instant rollback |
| Canary | Gradual rollout, risk reduction |
| Feature flags | Decouple deploy from release |
Generate CI/CD architectures at codelit.io — export GitHub Actions workflows, Docker configs, and Kubernetes manifests from any diagram.
Try it on Codelit
GitHub Integration
Paste a repo URL and generate architecture from your actual codebase
Related articles
Try these templates
OpenAI API Request Pipeline
7-stage pipeline from API call to token generation, handling millions of requests per minute.
8 componentsGitHub-like CI/CD Pipeline
Continuous integration and deployment system with parallel jobs, artifact caching, and environment management.
9 componentsMachine Learning Pipeline
End-to-end ML platform with data ingestion, feature engineering, training, serving, and monitoring.
8 componentsBuild this architecture
Generate an interactive architecture for CI/CD Pipeline Design in seconds.
Try it in Codelit →
Comments