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
| Topic | What it covers | |
|---|---|---|
| Pipeline stages and artefacts | A pipeline is a sequence of stages, and each stage exists to catch a class of problem as early and as cheaply as | lesson |
| Gates, secrets and deploys | A gate is a condition that must hold before code moves forward. Gates are what make a pipeline a control rather than a | lesson |
| Building and publishing container images in CI | Build with buildx and cache layers, tag by commit and branch, push to a registry, scan for vulnerabilities, and | lesson |
| Testing strategy inside the pipeline | Run only the tests affected by a change once the suite is large. It requires a reliable dependency graph, so start with | lesson |
| Environment promotion and release strategies | A canary is only as good as the metric that decides it. Latency and error rate on the new version, compared with the | lesson |
| Observability and speeding up slow pipelines | Queue wait is invisible in the workflow file and often the largest term. Measure wall-clock time from commit to first | lesson |
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-stdinFull 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,highFull 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_durationsFull 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.
Related cheat sheets
Git Linux Docker Kubernetes Nginx Bash Scripting
Last refreshed 2026-09-27.