| name | ci-cd-pipeline |
| description | Design and implement CI/CD pipelines for automated testing and deployment. Use when this capability is needed. |
| metadata | {"author":"furkangonel"} |
CI/CD Pipeline SOP
When to Use
- User wants to set up CI/CD for a project
- User asks about GitHub Actions, GitLab CI, CircleCI, or similar tools
- User wants to automate testing, building, or deployment
- User's pipeline is failing and they need to debug it
Part 1 — Pipeline Anatomy
Every solid pipeline has these stages in order:
Trigger → Lint → Test → Build → Security Scan → Deploy → Notify
| Stage | Purpose | Fail behavior |
|---|
| Lint | Code style, static analysis | Block PR merge |
| Test | Unit + integration tests | Block PR merge |
| Build | Compile / package / containerize | Block PR merge |
| Security Scan | SAST, dependency audit, secret detection | Block or warn |
| Deploy: Staging | Push to staging environment | Block prod deploy |
| Smoke Test | Quick sanity check on staging | Block prod deploy |
| Deploy: Prod | Production release | Notify team |
Part 2 — GitHub Actions Templates
Template A — Node.js Full Pipeline
name: CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: "20"
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
lint:
name: Lint & Type Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
-
[]
[, ]
[, ]
Template B — Matrix Strategy (multi-version testing)
jobs:
test:
strategy:
fail-fast: false
matrix:
node: ["18", "20", "22"]
os: [ubuntu-latest, macos-latest]
exclude:
- os: macos-latest
node: "18"
runs-on: ${{ matrix.os }}
name: Test (Node ${{ matrix.node }} / ${{ matrix.os }})
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci && npm test
Template C — Reusable Workflow
name: Reusable Deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
image-tag:
required: true
type: string
secrets:
DEPLOY_KEY:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- name: Deploy ${{ inputs.image-tag }} to ${{ inputs.environment }}
run: echo "Deploying..."
jobs:
call-deploy:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
image-tag: ${{ needs.build.outputs.image-tag }}
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
Part 3 — Secrets Management
GitHub Actions Secrets
- name: Set up credentials
env:
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
API_KEY: ${{ secrets.API_KEY }}
run: ./scripts/configure.sh
Secret Scanning
Add to your pipeline to prevent secret leaks:
- name: Scan for secrets
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
head: HEAD
Rules for Secrets
- Never hardcode secrets in workflow files
- Never
echo $SECRET or print to logs
- Rotate secrets if a workflow run is public and accidentally logged one
- Use
${{ secrets.NAME }} — GitHub automatically masks these in logs
Part 4 — Deployment Strategies
Rolling Update (Kubernetes)
kubectl set image deployment/app app=ghcr.io/myorg/app:sha-abc123
kubectl rollout status deployment/app
kubectl rollout undo deployment/app
Blue-Green
steps:
- name: Deploy to Green
run: deploy.sh green ${{ env.IMAGE_TAG }}
- name: Smoke test Green
run: curl -f https://green.example.com/health
- name: Switch traffic to Green
run: switch-traffic.sh green
- name: Keep Blue on standby for rollback
Canary (Argo Rollouts / Flagger)
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 100
Part 5 — Common Failure Patterns and Fixes
| Symptom | Likely Cause | Fix |
|---|
| Tests pass locally, fail in CI | Missing env var or service | Add service container or secret |
| Build slow (> 5min for npm ci) | No caching configured | Add cache: "npm" to setup-node |
| Docker push fails | Not logged in to registry | Add docker/login-action step |
| Deploy triggers on wrong branch | if: condition missing | Add if: github.ref == 'refs/heads/main' |
| Old job still running after new push | No concurrency config | Add concurrency.cancel-in-progress: true |
| Pipeline succeeds but app is broken | No smoke test | Add health check step after deploy |
Agent Instructions
- Ask the user which CI platform they're using (GitHub Actions, GitLab CI, CircleCI, etc.) before generating config
- Ask what languages and deployment targets are involved
- Always include caching for dependency installation — it's the biggest speed win
- Never put secrets in workflow files — always use
secrets.*
- Add
concurrency at the top level to avoid wasted runs
- Suggest adding a smoke test / health check after every deployment step
- Use
environment: with approval gates for production deploys
Source: furkangonel/cowrangler — distributed by TomeVault.