CI / CD cheat sheet

A scannable CI / CD reference: 9 short snippets across 6 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
Pipeline stages and artefactsA pipeline is a sequence of stages, and each stage exists to catch a class of problem as early and as cheaply aslesson
Gates, secrets and deploysA gate is a condition that must hold before code moves forward. Gates are what make a pipeline a control rather than alesson
Building and publishing container images in CIBuild with buildx and cache layers, tag by commit and branch, push to a registry, scan for vulnerabilities, andlesson
Testing strategy inside the pipelineRun only the tests affected by a change once the suite is large. It requires a reliable dependency graph, so start withlesson
Environment promotion and release strategiesA canary is only as good as the metric that decides it. Latency and error rate on the new version, compared with thelesson
Observability and speeding up slow pipelinesQueue wait is invisible in the workflow file and often the largest term. Measure wall-clock time from commit to firstlesson

Quick snippets

Pipeline stages and artefacts

Stages

# cheap feedback first, expensive stages later
stages: [lint, build, test, package, deploy]

lint:
  script: [npm ci, npm run lint]

build:
  script: [npm ci, npm run build]

test:
  script: [npm test]

Artefacts

# identify the artefact by the commit, not by "latest"
docker build -t registry.example.com/app:$GIT_SHA .
docker push  registry.example.com/app:$GIT_SHA

# deploy that exact image to staging, then the same one to production
kubectl set image deployment/app app=registry.example.com/app:$GIT_SHA

Keeping the pipeline fast

# cache dependency downloads between runs
cache:
  key: "$CI_COMMIT_REF_SLUG"
  paths:
    - node_modules/
    - .cache/pip

# run the slow suite in parallel shards
test:
  parallel: 4
  script: [npm test -- --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL]

Full lesson: Pipeline stages and artefacts →

Gates, secrets and deploys

Gates

  deploy:
    needs: [test]
    runs-on: ubuntu-latest
    environment: production        # attaches protection rules and approvals
    if: ${{ github.ref == 'refs/heads/main' }}
    steps:
      - run: ./deploy.sh

Secrets

      - name: Push image
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
        run: |
          echo "$REGISTRY_TOKEN" | docker login registry.example.com --password-stdin

Full lesson: Gates, secrets and deploys →

Building and publishing container images in CI

A Dockerfile that caches well

# build for two architectures and push both under one tag
docker buildx build --platform linux/amd64,linux/arm64 \
  -t ghcr.io/example/app:1.4.0 --push .

# inspect what is inside before trusting it
docker sbom ghcr.io/example/app:1.4.0
docker scout cves ghcr.io/example/app:1.4.0 --only-severity critical,high

Full lesson: Building and publishing container images in CI →

Testing strategy inside the pipeline

Splitting and reporting

# split by timing so each shard takes a similar time
npx jest --shard=1/4 --reporters=jest-junit
npx jest --shard=2/4 --reporters=jest-junit

# pytest: distribute by test duration from the previous run
pytest -n auto --dist loadfile --junitxml=reports/junit.xml

# once, record durations so the split is informed rather than arbitrary
pytest --store-durations --durations-path=.test_durations

Full lesson: Testing strategy inside the pipeline →

Environment promotion and release strategies

Rolling back and feature flags

# prefer rolling back to the previous known-good image over rebuilding
kubectl set image deployment/app app=ghcr.io/example/app@sha256:OLD_DIGEST
kubectl rollout status deployment/app --timeout=5m

# if the schema changed, the rollback needs a compatible migration first
./migrate.sh --to-version 42 --backward-compatible

# feature flags decouple deploy from release
curl -X PATCH https://flags.internal/api/v1/flags/checkout_v2 \
  -d '{"enabled": false, "environments": ["production"]}'

Full lesson: Environment promotion and release strategies →

Observability and speeding up slow pipelines

Metrics and alerting

# notify when the default branch has been red for more than 30 minutes
- name: Alert on long red
  if: failure() && github.ref == 'refs/heads/main'
  run: |
    ./notify.sh "Pipeline broken on main since ${{ github.run_started_at }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"

# and a weekly report of what is slow, so it gets fixed rather than endured
on:
  schedule:
    - cron: '0 9 * * 1'

Full lesson: Observability and speeding up slow pipelines →

FAQ

Is this CI / CD cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 6 lessons of the CI / CD course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full CI / CD course — it carries the worked explanations, the edge cases and the exercises behind every line here.

Git Linux Docker Kubernetes Nginx Bash Scripting

Last refreshed 2026-09-27.