Cheatsheet
A printable CI/CD cheatsheet covering pipeline stages, caching, secrets, environments, and the smallest YAML snippet for each. The one-pager you keep open during a CI rewrite.
CI/CD — printable cheatsheet
EXAMPLE
# ===== Stage map =====
# checkout -> install -> lint -> typecheck -> test -> build -> security-scan -> deploy
# ===== GitHub Actions skeleton =====
# .github/workflows/ci.yml
name: ci
on:
push: { branches: [main] }
pull_request:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
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 test -- --coverage
- run: npm run build
- uses: actions/upload-artifact@v4
with: { name: dist, path: dist/ }
# ===== Matrix builds =====
strategy:
fail-fast: false
matrix:
node: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
# ===== Caching =====
# Node modules: actions/setup-node cache:'npm' is usually enough
# Custom cache:
- uses: actions/cache@v4
with:
path: ~/.cache/foo
key: foo-${{ hashFiles('**/lock.json') }}
# ===== Secrets =====
# Repo: Settings -> Secrets and variables -> Actions
# Use: ${{ secrets.DEPLOY_KEY }}
# Never echo secrets. Mask with ::add-mask:: if needed.
# ===== Environments + manual approval =====
jobs:
deploy:
needs: build
environment:
name: production
url: https://example.com
steps:
- run: ./deploy.sh
# Configure 'production' env in Settings to require reviewers.
# ===== Conditional steps =====
- if: github.ref == 'refs/heads/main'
run: ./deploy.sh
- if: failure()
run: ./notify-slack.sh
- if: success() && github.event_name == 'pull_request'
run: ./preview-deploy.sh
# ===== Reusable workflows =====
# .github/workflows/reusable-test.yml
on:
workflow_call:
inputs:
node: { required: true, type: string }
jobs: { ... }
# Call from another workflow:
jobs:
test:
uses: ./.github/workflows/reusable-test.yml
with: { node: '20' }
# ===== GitLab CI skeleton =====
stages: [build, test, deploy]
build:
stage: build
script:
- npm ci
- npm run build
artifacts: { paths: [dist/] }
test:
stage: test
script: [npm test]
deploy:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == 'main'
script: ./deploy.sh
# ===== Common patterns =====
# - Fail fast: lint + typecheck before test before build
# - Cache deps; never cache build outputs
# - Run tests in parallel via matrix or test sharding
# - Required status checks on main; merge queue for serialised landings
# - Promote artifacts between stages, never rebuild
# - One pipeline per repo by default; split only when stages diverge sharply
# ===== Pitfalls =====
# - Secrets in PRs from forks -> use pull_request_target carefully
# - 'latest' image tags -> non-reproducible builds; pin shas
# - Long-running pipelines -> measure + parallelise + cache
# - Manual deploys after PR merge -> bake into pipeline so reverts are easy
# - No environment promotion -> staging != prod, surprises follow
Why it matters
Pin this above the desk during a pipeline overhaul. The patterns repeat across every CI provider: cached deps, parallel matrix, conditional deploys with manual gates. The provider syntax changes, the shape does not.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# checkout | setup-* | cache | upload-artifact | docker/build-push | environment | needsTry it Yourself »
Discussion
Loading…