CircleCI
Setting up CircleCI: project structure, .circleci/config.yml, orbs, caching, and a minimal pipeline that builds and tests.
CI/CD — CircleCI
EXAMPLE
# ===== The model =====
# CircleCI runs pipelines defined in .circleci/config.yml.
# Jobs run in Docker, machine VMs, or macOS executors.
# Workflows orchestrate jobs (sequence, parallel, manual approval, scheduled).
# ===== Minimal config (Node) =====
# .circleci/config.yml
version: 2.1
orbs:
node: circleci/node@5
jobs:
build_and_test:
docker:
- image: cimg/node:20.11
steps:
- checkout
- node/install-packages:
pkg-manager: npm
- run: npm run lint
- run: npm test -- --coverage
- store_test_results:
path: ./test-results
workflows:
ci:
jobs:
- build_and_test
# ===== Caching (free perf) =====
# The node orb caches node_modules by package-lock.json by default.
# Custom cache:
- save_cache:
key: deps-{{ checksum "package-lock.json" }}
paths: [node_modules]
- restore_cache:
keys: [deps-{{ checksum "package-lock.json" }}]
# ===== Workflows with approval =====
workflows:
release:
jobs:
- build_and_test
- deploy_staging:
requires: [build_and_test]
filters: { branches: { only: main } }
- hold_for_prod:
type: approval
requires: [deploy_staging]
- deploy_prod:
requires: [hold_for_prod]
# ===== Parallel test sharding =====
- run:
command: |
TESTS=$(circleci tests glob 'tests/**/*.test.ts' | circleci tests split --split-by=timings)
npx vitest $TESTS
parallelism: 4
# ===== Matrix builds =====
jobs:
test:
parameters:
node_version: { type: string }
docker:
- image: cimg/node:\<\< parameters.node_version \>\>
steps:
- checkout
- run: npm test
workflows:
ci:
jobs:
- test:
matrix:
parameters:
node_version: ['18.20', '20.11']
# ===== Secrets =====
# Project Settings -> Environment Variables (encrypted at rest).
# Use Contexts for multi-project shared secrets.
# Access in jobs as $VAR.
# ===== Orbs (reusable building blocks) =====
# node, python, docker, aws-cli, kubernetes, browser-tools, slack
# Browse: circleci.com/orbs
# Pin orb versions; do not float major versions.
# ===== Useful runtime tweaks =====
# resource_class: medium / large / xlarge for more CPU/RAM
# parallelism: 4 sharded jobs
# circleci/config.yml validation: circleci config validate
# ===== Patterns to internalise =====
# - Pin orb versions
# - Cache deps; never cache build outputs
# - Required status checks on the default branch
# - Manual approval gates before risky stages
# - Reuse with orbs / commands / executors
# ===== Pitfalls =====
# - Unused parallelism (paying for slots that sit idle)
# - Secrets in YAML / git history (use env vars or contexts)
# - Caching node_modules without a stable cache key -> cache thrash
# - 'latest' image tags -> non-reproducible builds
Why it matters
CircleCI configs are YAML + orbs + workflows. Cache deps, shard tests, gate prod with manual approval, and pin orb versions. The pipeline does the safety-net work; the gates absorb the risk you have not yet automated.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# .circleci/config.yml
version: 2.1
jobs:
test:
docker: [{ image: cimg/node:20.0 }]
steps:
- checkout
- run: npm ci
- run: npm test
Try it Yourself »
Discussion
Loading…