The cloud config is 2.1 — pin every file with that header
to unlock orbs, reusable commands, parameters, and dynamic config. Recent additions:
setup: true dynamic configs, OIDC tokens for cloud auth, ARM
resource classes, the cimg/* base image family. Avoid the legacy
version: 2 dialect — it lacks orbs and parameters.
config.yml · CLISetup
bash
# 1. Minimal .circleci/config.yml at repo root
mkdir -p .circleci
cat > .circleci/config.yml <<'YAML'
version: 2.1
jobs:
test:
docker: [{ image: cimg/python:3.12 }]
steps:
- checkout
- run: pip install -r requirements.txt
- run: pytest -q
workflows:
ci:
jobs: [test]
YAML
git add .circleci/config.yml && git commit -m "ci: enable circleci" && git push
# 2. CLI — local validation + local job runs
brew install circleci # macOS
# Or: curl -fLSs https://raw.githubusercontent.com/CircleCI-Public/circleci-cli/main/install.sh | bash
circleci version
circleci setup # interactive token setup
# 3. Validate config without pushing
circleci config validate # syntax + semantic check
circleci config process .circleci/config.yml # show the expanded YAML (after orbs)
# 4. Run a single job locally (in Docker)
circleci local execute --job test
# 5. Connect a repo
# Web UI: app.circleci.com → Projects → Set Up Project
Top-level keysconfig.yml structure
version: 2.1
Required first line. Unlocks orbs / commands / parameters.
orbs:
Pull in reusable packages of jobs / commands / executors.
executors:
Named executor definitions reused by multiple jobs.
commands:
Reusable step sequences with parameters.
parameters:
Pipeline-level parameters — typed, surfaced in the UI.
jobs:
Job definitions. Each job has an executor + steps.
Always pair parallelism with store_test_results.
Without junit data the splitter falls back to filename hashing — shards drift and one container ends
up with all the slow tests. Upload junit-${CIRCLE_NODE_INDEX}.xml per shard and
the next run distributes evenly by historical timing.
Bake the version prefix into every cache key.
Caches are immutable, so v1-... becomes a dead branch once you change
shape. Starting with v1- means you can bump to v2-
in one commit and force a fresh cache without renaming the project.
Use orbs for cloud auth, not static keys.circleci/aws-cli + circleci/gcp-cli both support OIDC.
You declare a role ARN, CircleCI hands the role a JWT, the role hands back short-lived creds. No
AWS_ACCESS_KEY_ID in project settings to rotate or leak.
Common trapsWatch out for
Caches are immutable per key — you can’t patch one.
Once written, a key’s value is fixed forever. The fallback prefix in
restore_cache.keys is how you migrate cleanly. Forgetting that turns
"we updated the cache" into "the new step never runs".
Tag triggers don’t fire on default branch filters.
A workflow with no tags: filter ignores tag pushes entirely. If you want a
tag-only release pipeline, you must set filters.tags.onlyandfilters.branches.ignore: /.*/ on the job.
Orbs drift between minor versions.circleci/python@2 follows the latest 2.x — behaviour can change on push from the
orb publisher. Pin to @2.1 or exact @2.1.4 for
reproducible pipelines.
An orb is a reusable, shareable package of CircleCI configuration that bundles jobs, commands, and executors. First-party orbs like circleci/python or circleci/node let you add common steps in one line instead of duplicating YAML across projects.
What is the difference between a cache and a workspace in CircleCI?
Caches persist data across pipeline runs and are keyed for reuse (e.g., dependency caches). Workspaces are ephemeral within a single pipeline and pass files between jobs in the same workflow, such as handing build artifacts to a deploy job.
How does CircleCI parallelism work?
Set parallelism: N on a job to spin up N containers running the same steps concurrently. Use circleci tests split to divide test files across containers by timing data, then combine results with store_test_results so CircleCI merges the JUnit output.
What is a CircleCI context?
A context is a named group of environment variables stored in your org settings and injected into jobs at runtime. Assign context: [my-context] in the workflow block. OIDC token injection lets jobs authenticate to cloud providers without storing long-lived secrets.
What is dynamic config in CircleCI?
Dynamic config lets a setup workflow generate the real pipeline config at runtime instead of committing a static file. Mark the file with setup: true, use the continuation orb to emit the generated config, and CircleCI will execute that second config as the main pipeline.
How do I run CircleCI locally?
Install the CircleCI CLI (brew install circleci or the Linux installer) and run circleci local execute --job <job-name>. This requires Docker and runs your job inside a local container, which is useful for debugging before pushing to the cloud.