Configuration reference
This document is a reference for the CircleCI 2.x configuration keys that are used in the .circleci/config.yml file.
You can see a complete config.yml in our full example.
version
The version field is intended to be used in order to issue warnings for deprecation or breaking changes.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
|
Example:
version: 2.1
setup
The setup field enables you to conditionally trigger configurations from outside the primary .circleci parent directory, update pipeline parameters, or generate customized configurations.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Boolean |
Designates the |
Example:
version: 2.1
setup: true
orbs
The orbs key is supported in version: 2.1 configuration
|
Use the orbs key to reference or define reusable configuration blocks (orbs) for use in your configuration.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Map |
A map of user-selected names to either: orb references (strings) or orb definitions (maps). Orb definitions must be the orb-relevant subset of 2.1 config. See the Creating Orbs documentation for details. |
|
N |
Map |
A map of strings to executor definitions. See the |
|
N |
Map |
A map of command names to command definitions. See the |
The following example uses the node orb that exists in the certified circleci namespace. Refer to the Node orb page in the Orb Registry for more examples and information.
Example:
version: 2.1
orbs:
node: circleci/node@x.y
jobs:
install-node-example:
docker:
- image: cimg/base:stable
steps:
- checkout
- node/install:
install-yarn: true
node-version: '16.13'
- run: node --version
workflows:
test_my_app:
jobs:
- install-node-example
Documentation is available for orbs in the following sections:
Public orbs are listed in the Orb Registry.
commands
The commands key is supported in version: 2.1 configuration
|
A command defines a sequence of steps as a map to be executed in a job, enabling you to reuse a single command definition across multiple jobs. For more information see the Reusable Config Reference Guide.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
Sequence |
A sequence of steps run inside the calling job of the command. |
|
N |
Map |
A map of parameter keys. See the Parameter Syntax section of the Reusing Config document for details. |
|
N |
String |
A string that describes the purpose of the command. |
Example:
version: 2.1
commands:
sayhello:
description: "A very simple command for demonstration purposes"
parameters:
to:
type: string
default: "Hello World"
steps:
- run: echo << parameters.to >>
parameters
The pipeline parameters key is supported in version: 2.1 configuration
|
Use the parameters key at the top level of your config to declare pipeline parameters for use in the configuration. See Pipeline Values and Parameters for usage details.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Map |
A map of parameter keys. Supports |
Example:
This example declares a pipeline parameter named image-tag with a type of string and a default value of current.
version: 2.1
parameters:
image-tag:
type: string
default: "current"
Once you have declared a pipeline parameter, you can pass a pipelines parameter value when triggering a pipeline via the API or from the CircleCI web app. '''
executors
The executors key is supported in version: 2.1 configuration
|
Executors define the execution environment where job steps run, letting you reuse a single executor definition across multiple jobs.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y (1) |
List |
Options for Docker executor |
|
N |
String |
Amount of CPU and RAM allocated to each container in a job. |
|
Y (1) |
Map |
Options for machine executor |
|
Y (1) |
Map |
Options for macOS executor |
|
Y (1) |
Map |
Windows executor currently working with orbs. Check out the orb. |
|
N |
String |
Shell to use for execution command in all steps. Can be overridden by |
|
N |
String |
The directory where steps run. CircleCI interprets this as an absolute path. |
|
N |
Map |
A map of environment variable names and values. |
(1) Specify one executor type per job. If you set more than one, CircleCI returns an error.
Example:
version: 2.1
executors:
my-executor:
docker:
- image: cimg/ruby:3.0.3-browsers
jobs:
my-job:
executor: my-executor
steps:
- run: echo "Hello executor!"
See the Using Parameters in Executors section of the Reusing Config page for examples of parameterized executors.
jobs
A Workflow is comprised of one or more uniquely named jobs. Jobs are specified in the jobs map, see Sample Config.yml for two examples of a job map. The name of the job is the key in the map, and the value is a map describing the job.
Jobs have a maximum runtime based on pricing plan, as follows:
-
1 hour (Free).
-
3 hours (Performance).
-
5 hours (Scale).
If your jobs are timing out, consider the following:
-
A larger
resource_class. -
Using Parallelism.
-
Run some of your jobs concurrently using Workflows.
-
You can upgrade your pricing plan.
Example:
version: 2.1
jobs:
my-job:
docker:
- image: cimg/base:2024.12
resource_class: xlarge
steps:
... // other config
<job_name>
Each job consists of the job’s name as a key and a map as a value. A name should be case insensitive unique within a current jobs list. The value map has the following attributes:
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
String |
Job type, can be |
|
Y (1) |
List |
Options for the Docker executor |
|
Y (1) |
Map |
Options for the machine executor |
|
Y (1) |
Map |
Options for the macOS executor |
|
Y (1) |
String |
Name of a declared reusable executor |
|
N |
String |
Shell to use for execution command in all steps. Can be overridden by |
|
N |
Map |
Parameters for making a |
|
Y |
List |
A list of steps to be performed |
|
N |
String |
The directory where steps run. CircleCI interprets this as an absolute path. Default: |
|
N |
Integer |
Number of parallel instances of this job to run (default: 1) |
|
N |
Map |
A map of environment variable names and values. |
|
N |
Map |
This key is deprecated. Use workflows filtering to control which jobs run for which branches. |
|
N |
String |
Amount of CPU and RAM allocated to each container in a job. |
|
N |
Map |
Configure job retention periods for cache data (1-15 days, for example, "1d", "7d", "15d"). This reduces retention from the organization-level default, automatically removing cache data after the specified period. |
(1) Specify one executor type per job. If you set more than one, CircleCI returns an error.
Example:
In this example the job name is my-job.
version: 2.1
jobs:
my-job:
type
Configure a job type. Options are release, approval, no-op, build (default).
If a type is not specified, the job defaults to a build type.
Example of a job with a build type. build is the default type and does not need to be configured:
jobs:
my-job:
docker:
- image: cimg/base:2024.12
resource_class: xlarge
steps:
... // other config
Jobs with the release type are used to Connect Your Pipeline Configuration to a deployment in the CircleCI deploys UI. For full details, see the Deploys Overview page.
Example of a job with a release type:
jobs:
release-my-service:
type: release
plan_name: <my-service-release>
The no-op type is used to configure a job that performs no actions and consumes no credits. no-op is commonly used to organise the order of operations within a workflow and make it easier to maintain. Only the type is required for a no-op type job, no further job configuration is required. For some examples of using no-op jobs, see the Orchestration Cookbook
Example of a job with a no-op type:
jobs:
my-no-op-job:
type: no-op
The approval type is used to configure a manual approval step. No job configuration is required or allowed for an approval type job. The approval type is most commonly configured within a workflow rather than under the top-level jobs key. Only approval type jobs can have their type configured under workflows. See type under workflows section for full details.
Example of a job with an approval type, configured under workflows:
workflows:
my-workflow:
jobs:
- build
- test:
requires:
- build
- hold:
type: approval
requires:
- test
- deploy:
requires:
- hold
environment
A map of environment variable names and values. For more information on defining and using environment variables, and the order of precedence governing the various ways they can be set, see the Environment Variables page.
Example to show setting an environment variable named FOO with a value of bar for use in a job.
version: 2.1
jobs:
build:
docker:
- image: cimg/base:2022.04-20.04
environment:
FOO: bar
retention
Configure job retention periods to control how long job data is kept. Job retention specifically controls cache retention at the job level. This setting can be configured from 1 day to 15 days using string values (for example, "1d", "7d", "15d"). Job retention reduces the organization-level retention from the default by automatically removing cache data after the specified period.
Example:
version: 2.1
jobs:
test:
docker:
- image: cimg/node:18.0
retention:
caches: 7d
steps:
- checkout
- run: npm install
- run: npm test
For more information on cache retention, see the Persisting Data Overview page.
Common errors
When configuring job retention, you may encounter the following validation errors:
-
Invalid time format: The retention period must use the format
^([1-9]|[12][0-9]|30)d$(1-30 days with "d" suffix). For example, use"7d"instead of"12h"or"1w". -
Incorrect data type: The
retentionkey expects a map withcachesas a string value, not a direct string.
Examples:
# Incorrect - direct string value
jobs:
say-hello:
retention: "12h" # Error: expected type: String, found: Mapping
#Incorrect - invalid time format
jobs:
say-hello:
retention:
caches: "12h" # Error: does not match pattern ^([1-9]|[12][0-9]|30)d$
# Correct format
jobs:
say-hello:
retention:
caches: "7d" # Valid: 7 days
parallelism
Use this feature to optimize test steps. If you set parallelism to N > 1, CircleCI sets up N independent executors, and each runs the job’s steps in parallel.
You can use the CircleCI CLI to split your test suite across parallel containers so the job completes in a shorter time.
-
Read more about splitting tests across parallel execution environments on the Parallelism and Test Splitting page.
-
Refer to the Use the CircleCI CLI to Split Tests how-to guide.
-
Follow the Test Splitting Tutorial.
-
Use an integer
-
Use an expression
jobs:
build:
docker:
- image: cimg/base:2024.12
environment:
FOO: bar
parallelism: 3
resource_class: large
working_directory: ~/my-app
steps:
- run: go list ./... | circleci tests run --command "xargs gotestsum --junitfile junit.xml --format testname --" --split-by=timings --timings-type=name
jobs:
build:
docker:
- image: cimg/base:2024.12
environment:
FOO: bar
parallelism: << pipeline.git.branch == "main" and 10 or 1 >>
resource_class: large
working_directory: ~/my-app
steps:
- run: go list ./... | circleci tests run --command "xargs gotestsum --junitfile junit.xml --format testname --" --split-by=timings --timings-type=name
parameters
Job-level parameters can be used when calling a job in a workflow.
Reserved parameter-names:
-
name -
requires -
context -
type -
filters -
matrix
See Parameter Syntax for definition details.
Example to show using a job parameter to set the parallelism for a job when a workflow is run.
version: 2.1
jobs:
build:
parameters:
my-parameter:
type: integer
default: 1
parallelism: << parameters.my-parameter >>
docker:
- image: cimg/base:2023.11
steps:
- checkout
workflows:
workflow:
jobs:
- build:
my-parameter: 2
Executor docker / machine / macos
CircleCI offers several execution environments in which to run your jobs. To specify an execution environment choose an executor, then specify and image and a resource class. An executor defines the underlying technology, environment, and operating system in which to run a job.
Set up your jobs to run using the docker (Linux), machine (LinuxVM, Windows, GPU, Arm), or macos executor, then specify an image with the tools and packages you need, and a resource class.
Learn more about execution environments and executors in the Introduction to Execution Environments.
docker
Configure a job to use the Docker execution environment using the docker key which takes a list of maps:
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
The name of a custom Docker image to use. The first |
|
N |
String |
|
|
N |
String or List |
The command used as executable when launching the container. |
|
N |
String or List |
The command to use as PID 1 (or as arguments for entrypoint) when launching the container. |
|
N |
String |
Which user to run commands as within the Docker container |
|
N |
Map |
A map of environment variable names and values. The |
|
N |
Map |
Authentication for registries using standard |
|
N |
Map |
Authentication for AWS Elastic Container Registry (ECR) |
For a Primary Container, (the first container in the list) if neither command nor entrypoint is specified in the configuration, then any ENTRYPOINT and COMMAND in the image are ignored. The primary container is typically only used for running the steps and not for its ENTRYPOINT, and an ENTRYPOINT may consume significant resources or exit prematurely.
A Custom Image may disable this behavior and force the ENTRYPOINT to run.
You can specify image versions using tags or digest. You can use any public images from any public Docker registry (defaults to Docker Hub). Learn more about specifying images on the Using the Docker Execution Environment page.
Example:
version: 2.1
jobs:
hello-job:
docker:
- image: cimg/node:17.2.0 # the primary container, where your job's commands are run
steps:
- checkout # check out the code in the project directory
- run: echo "hello world" # run the `echo` command
workflows:
my-workflow:
jobs:
- hello-job
Docker registry authentication
Some registries, Docker Hub, for example, may rate limit anonymous Docker pulls. We recommend that you authenticate to pull private and public images. The username and password can be specified in the auth field. See Using Docker Authenticated Pulls for details.
Example:
jobs:
build:
docker:
- image: buildpack-deps:trusty # primary container
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
environment:
ENV: CI
- image: mongo:2.6.8
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
command: [--smallfiles]
- image: postgres:14.2
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
environment:
POSTGRES_USER: user
- image: redis@sha256:54057dd7e125ca41afe526a877e8bd35ec2cdd33b9217e022ed37bdcf7d09673
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
- image: acme-private/private-image:321
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
AWS authentication
Using an image hosted on AWS ECR requires authentication using AWS credentials. The two configuration options are described in the following sections.
Use OIDC
Authenticate using OpenID Connect (OIDC) using the oidc_role_arn field, as follows:
Example:
jobs:
job_name:
docker:
- image: <your-image-arn>
aws_auth:
oidc_role_arn: <your-iam-role-arn>
For steps to get set up with OIDC to pull images from AWS ECR, see the Pull an Image From AWS ECR With OIDC page.
Use environment variables
By default, CircleCI uses the AWS credentials you provide by setting the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY project environment variables. It is also possible to set the credentials by using the aws_auth field as in the following example:
Example:
jobs:
build:
docker:
- image: account-id.dkr.ecr.us-east-1.amazonaws.com/org/repo:0.1
aws_auth:
aws_access_key_id: AKIAQWERVA # can specify string literal values
aws_secret_access_key: $ECR_AWS_SECRET_ACCESS_KEY # or project UI envar reference
machine
Using CircleCI Cloud? The use of machine: true is deprecated. You must specify an image to use.
|
The machine executor is configured using the machine key, which takes a map:
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
The virtual machine image to use. View available images. Note: This key is not supported for Linux VMs on installations of CircleCI Server. For information about customizing |
|
N |
Boolean |
Set this to |
Example:
-
Cloud
-
Server
jobs:
build: # name of your job
machine: # executor type
image: ubuntu-2004:current # recommended linux image
steps:
# Commands run in a Linux virtual machine environment
jobs:
build: # name of your job
machine: true # executor type
steps:
# Commands run in a Linux virtual machine environment
Linux machine images
Specifying an image in your configuration file is strongly recommended. CircleCI supports multiple Linux machine images that can be specified in the image field. For a full list of supported image tags, refer to the following pages in the Developer Hub:
More information on the software available in each image can be found in our Discuss forum.
The machine executor supports Docker Layer Caching, which is useful when you are building Docker images during your job or Workflow.
Linux machine images on server
If you are using CircleCI Server, contact your system administrator for details of available Linux machine images.
Linux GPU machine images
When using the Linux GPU Executor, the available images are:
-
linux-cuda-11:defaultv11.4, v11.6, v11.8 (default), Docker v20.10.24. -
linux-cuda-12:defaultv12.0, v12.1 (default), Docker v20.10.24.
Android machine images
CircleCI supports running jobs on Android for testing and deploying Android applications.
To use the Android image directly with the machine executor, add the following to your job:
version: 2.1
jobs:
build:
machine:
image: android:2024.11.1
The Android image can also be accessed using the Android orb.
For examples, refer to the Using Android Images With the Machine Executor page.
Windows machine images
Specifying an image in your configuration file is strongly recommended. CircleCI supports multiple Windows machine images that can be specified in the image field.
For a full list of supported images, refer to one of the following:
More information on what software is available in each image can be found in our Discuss forum.
Alternatively, use the Windows orb to manage your Windows execution environment. For examples, see the Using the Windows Execution Environment page.
Windows machine images on server
If you are using CircleCI Server, contact your system administrator for details of available Windows machine images.
Windows GPU machine image
When using the Windows GPU Executor, the available image is:
Example:
version: 2.1
jobs:
build:
machine:
image: windows-server-2019-cuda:current
macos
CircleCI supports running jobs on macOS, to allow you to build, test, and deploy apps for macOS, iOS, tvOS and watchOS. To run a job on a macOS virtual machine, add the macos key to the top-level configuration for your job and specify the version of Xcode to use.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
The version of Xcode that is installed on the virtual machine, see the Supported Xcode Versions Section of the Testing iOS document for the complete list. |
Example: Use a macOS virtual machine with Xcode version 14.2.0:
jobs:
build:
macos:
xcode: "14.2.0"
branches - DEPRECATED
This key is deprecated. Use workflows filtering to control which jobs run for which branches.
resource_class
The resource_class feature allows you to configure CPU and RAM resources for each job. Resource classes are available for each execution environment, as described in the tables below.
We implement soft concurrency limits for each resource class to ensure our system remains stable for all customers. If you are on a Performance or Custom Plan and experience queuing for certain resource classes, it is possible you are hitting these limits. Contact CircleCI support to request a raise on these limits for your account.
If you do not specify a resource class, CircleCI uses a default value that can change. Specify a resource class instead of relying on a default.
Java, Erlang and any other languages that introspect the /proc directory for information about CPU count may require additional configuration to prevent them from slowing down when using the CircleCI resource class feature. Programs with this issue may request 32 CPU cores and run slower than they would when requesting one core. Users of languages with this issue should pin their CPU count to their guaranteed CPU resources.
|
If you want to confirm how much memory you have been allocated, you can check the cgroup memory hierarchy limit with grep hierarchical_memory_limit /sys/fs/cgroup/memory/memory.stat.
|
Self-hosted runner
Use the resource_class key to configure a Self-hosted Runner Instance.
For example:
jobs:
job_name:
machine: true
resource_class: <my-namespace>/<my-runner>
Docker execution environment
jobs:
build:
docker:
- image: cimg/base:2024.12
resource_class: xlarge
steps:
... // other config
jobs:
build:
docker:
- image: cimg/base:2024.12
resource_class: << pipeline.git.branch == "main" and xlarge or medium >>
steps:
... // other config
x86
| For credit and access information, see the Resource classes page. Resource class access is dependent on your Plan. |
| Class | vCPUs | RAM | Cloud | Server |
|---|---|---|---|---|
|
1 |
2GB |
||
|
2 |
4GB |
||
|
3 |
6GB |
||
|
4 |
8GB |
||
|
8 |
16GB |
||
|
16 |
32GB |
||
|
20 |
40GB |
Arm
| Class | vCPUs | RAM | Cloud | Server |
|---|---|---|---|---|
|
2 |
8 GB |
||
|
4 |
16 GB |
||
|
8 |
32 GB |
||
|
16 |
64 GB |
LinuxVM execution environment
| Class | vCPUs | RAM | Disk Size | Cloud | Server |
|---|---|---|---|---|---|
|
2 |
7.5 GB |
150GB |
||
|
4 |
15 GB |
150GB |
||
|
8 |
32 GB |
150GB |
||
|
16 |
64 GB |
150GB |
||
|
32 |
64 GB |
150GB |
Example:
-
Cloud
-
Server
jobs:
build:
machine:
image: ubuntu-2004:2024.01.2 # recommended linux image
resource_class: large
steps:
... // other config
jobs:
build:
machine: true
resource_class: large
steps:
... // other config
LinuxVM (gen2) execution environment
| Class | vCPUs | RAM | Disk Size | Cloud | Server |
|---|---|---|---|---|---|
|
2 |
8 GiB |
150GB |
||
|
4 |
16 GiB |
150GB |
||
|
8 |
32 GiB |
150GB |
||
|
16 |
64 GiB |
150GB |
||
|
32 |
128 GiB |
150GB |
Example:
-
Cloud
-
Server
jobs:
build:
machine:
image: ubuntu-2404:current # recommended linux image
resource_class: large.gen2
steps:
... // other config
jobs:
build:
machine: true
resource_class: large.gen2
steps:
... // other config
macOS execution environment
| Class | vCPUs | RAM | Cloud | Server |
|---|---|---|---|---|
|
6 @ 4.51 GHz |
28GB |
||
|
12 @ 4.51 GHz |
56GB |
||
|
4 @ 3.49 GHz |
8GB |
||
|
8 @ 3.49 GHz |
16GB |
||
|
4 @ 3.2 GHz |
6GB |
||
|
8 @ 3.2 GHz |
12GB |
Example:
jobs:
build:
macos:
xcode: "15.4.0"
resource_class: m2pro.medium
steps:
... // other config
macOS execution environment on server
If you are working on CircleCI Server you can access the macOS execution environment using Self-hosted Runner.
Windows execution environment
| Class | vCPUs | RAM | Disk Size | Cloud | Server |
|---|---|---|---|---|---|
|
4 |
15GB |
200 GB |
||
|
8 |
30GB |
200 GB |
||
|
16 |
60GB |
200 GB |
||
|
32 |
128GB |
200 GB |
| Using server? Check with your systems administrator whether you have access to the Windows execution environment. |
Example:
-
Cloud
-
Server
version: 2.1
jobs:
build: # name of your job
resource_class: 'windows.medium'
machine:
image: 'windows-server-2022-gui:current'
shell: 'powershell.exe -ExecutionPolicy Bypass'
steps:
# Commands are run in a Windows virtual machine environment
- checkout
- run: Write-Host 'Hello, Windows'
version: 2.1
jobs:
build: # name of your job
machine:
image: windows-default
steps:
# Commands are run in a Windows virtual machine environment
- checkout
- run: Write-Host 'Hello, Windows'
GPU execution environment (Linux)
| Class | vCPUs | RAM | GPUs | GPU model | GPU Memory (GiB) | Disk Size (GiB) | Cloud | Server |
|---|---|---|---|---|---|---|---|---|
|
4 |
16 |
1 |
NVIDIA Tesla P4 |
16 |
150 |
||
|
4 |
16 |
1 |
NVIDIA A10G |
24 |
150 |
||
|
4 |
15 |
2 |
NVIDIA Tesla T4 |
16 |
150 |
||
|
8 |
30 |
4 |
NVIDIA Tesla T4 |
16 |
150 |
||
|
8 |
30 |
1 |
NVIDIA Tesla T4 |
16 |
150 |
||
|
8 |
30 |
1 |
NVIDIA Tesla V100 |
16 |
150 |
Example:
version: 2.1
jobs:
build:
machine:
image: linux-cuda-12:default
resource_class: gpu.nvidia.medium
steps:
- run: nvidia-smi
- run: docker run --gpus all nvidia/cuda:9.0-base nvidia-smi
See the Available Linux GPU images section for the full list of available images.
GPU execution-environment (Windows)
| Class | vCPUs | RAM | GPUs | GPU model | GPU Memory (GiB) | Disk Size (GiB) | Cloud | Server |
|---|---|---|---|---|---|---|---|---|
|
16 |
60 |
1 |
NVIDIA Tesla T4 |
16 |
200 |
Example:
version: 2.1
orbs:
win: circleci/windows@5.0.0
jobs:
build:
executor: win/server-2019-cuda
steps:
- checkout
- run: '&"C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe"'
(2) This resource requires review by our support team. Open a support ticket if you would like to request access.
Arm VM execution-environment
| Class | vCPUs | RAM | Disk Size | Cloud | Server |
|---|---|---|---|---|---|
|
2 |
8GB |
100 GB |
||
|
4 |
16GB |
100 GB |
||
|
8 |
32GB |
100 GB |
||
|
16 |
64GB |
100 GB |
| Using server? Check with your systems administrator whether you have access to the Arm execution environment. |
Example:
-
Cloud
-
Server
jobs:
my-job:
machine:
image: ubuntu-2004:2024.01.2
resource_class: arm.medium
steps:
- run: uname -a
- run: echo "Hello, Arm!"
jobs:
my-job:
machine:
image: arm-default
resource_class: arm.medium
steps:
- run: uname -a
- run: echo "Hello, Arm!"
steps
The steps setting in a job should be a list of single key/value pairs, the key of which indicates the step type. The value may be either a configuration map or a string (depending on what that type of step requires). For example, using a map:
jobs:
build:
docker:
- image: cimg/base:2024.01
working_directory: ~/canary-python
environment:
FOO: bar
steps:
- run:
name: Running tests
command: make test
Here run is a step type. The name attribute is used by the UI for display purposes. The command attribute is specific for run step and defines command to execute.
Some steps may implement a shorthand semantic. For example, run may be also be called like this:
jobs:
build:
docker:
- image: cimg/base:2024.01
steps:
- run: make test
In its short form, the run step allows us to directly specify which command to execute as a string value. In this case step itself provides default suitable values for other attributes (name here has the same value as command, for example).
Another shorthand, which is possible for some steps, is to use the step name as a string instead of a key/value pair:
jobs:
build:
docker:
- image: cimg/base:2024.01
steps:
- checkout
In this case, the checkout step checks out project source code into the job’s working_directory.
In general all steps can be described as:
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
Map or String |
A configuration map for the step or some string whose semantics are defined by the step. |
Each built-in step is described in detail below.
run
Use the run step to invoke command-line programs. The run step takes either a map of configuration values, or, when you call it in short-form, a string that serves as both the command and name. CircleCI executes run commands using non-login shells by default, so you must explicitly source any dotfiles as part of the command.
the run step replaces the deprecated deploy step. If your job has a parallelism of 1, the deprecated deploy step can be swapped out directly for the run step. If your job has parallelism > 1, see Migrate From Deploy to Run.
|
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
Command to run via the shell |
|
N |
String |
Title of the step to be shown in the CircleCI UI (default: full |
|
N |
String |
Shell to use for execution command (default: See Default Shell Options) |
|
N |
Map |
Additional environment variables, locally scoped to command |
|
N |
Boolean |
Whether or not this step should run in the background (default: false) |
|
N |
String |
The directory where this step runs. CircleCI interprets this relative to the |
|
N |
String |
Elapsed time the command can run without output. The string is a decimal with unit suffix, such as "20m", "1.25h", "5s". The default is 10 minutes and the maximum is governed by the maximum time a job is allowed to run. |
|
N |
String |
Specify when to enable or disable the step. Takes the following values: |
|
N |
Integer |
The maximum number of times to automatically rerun the step if it fails. Must be between |
|
N |
String |
The delay between reruns of the step if it fails. This delay can only be set along with |
Each run declaration represents a new shell. You can specify a multi-line command where each line runs in the same shell.
Example:
jobs:
my-job:
docker:
- image: cimg/base:2024.12
resource_class: xlarge
steps:
- run:
command: |
echo Running test
mkdir -p /tmp/test-results
make test
You can also configure commands to run in the background if you do not want to wait for the step to complete before moving on to subsequent run steps.
Default shell options
For jobs that run on Linux, CircleCI defaults the shell option to /bin/bash -eo pipefail if /bin/bash exists in the build container. Otherwise, CircleCI uses /bin/sh -eo pipefail. The default shell is not a login shell (CircleCI does not specify --login or -l) and thus does not source your ~/.bash_profile, ~/.bash_login, or ~/.profile files.
For jobs that run on macOS, the default shell is /bin/bash --login -eo pipefail. The shell is a non-interactive login shell. The shell executes /etc/profile/ followed by ~/.bash_profile before every step.
For more information about which files are executed when Bash is invocated, see the INVOCATION section of the bash manpage.
Descriptions of the -eo pipefail options are provided below.
-e
Exit immediately if any of the following exits with a non-zero status:
-
A pipeline (which may consist of a single simple command).
-
A subshell command enclosed in parentheses.
-
One of the commands executed as part of a command list enclosed by braces.
In the previous example, mkdir failed to create a directory and returned a non-zero status, so the shell terminated command execution and marked the whole step as failed. If you want the opposite behavior, add set +e in your command or override the default shell in your run configuration map. For example:
Example:
- run:
command: |
echo Running test
set +e
mkdir -p /tmp/test-results
make test
- run:
shell: /bin/sh
command: |
echo Running test
mkdir -p /tmp/test-results
make test
-o pipefail
If pipefail is enabled, the pipeline’s return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. The shell waits for all commands in the pipeline to terminate before returning a value.
Example:
- run: make test | tee test-output.log
If make test fails, the -o pipefail option will cause the whole step to fail. Without -o pipefail, the step will always run successfully because the result of the whole pipeline is determined by the last command (tee test-output.log), which will always return a zero status.
If make test fails the rest of pipeline will be executed.
|
If you want to avoid this behaviour, you can specify set +o pipefail in the command or override the whole shell (see example above).
In general, we recommend using the default options (-eo pipefail) because they show errors in intermediate commands and simplify debugging job failures. For convenience, the UI displays the used shell and all active options for each run step.
For more information, see the Using Shell Scripts document.
Background commands
The background attribute enables you to configure commands to run in the background. Job execution proceeds to the next step rather than waiting for return of a command with the background attribute set to true. The following example shows the configuration for running the X virtual framebuffer in the background which is commonly required to run Selenium tests.
Example:
- run:
name: Running X virtual framebuffer
command: Xvfb :99 -screen 0 1280x1024x24
background: true
- run: make test
Shorthand syntax
run has a convenient shorthand syntax.
Example:
- run: make test
# shorthanded command can also have multiple lines
- run: |
mkdir -p /tmp/test-results
make test
In this case, command and name become the string value of run, and the rest of the config map for that run have their default values.
The when attribute
By default, CircleCI executes job steps one at a time, in the order you define them in config.yml, until a step fails (returns a non-zero exit code). After a command fails, no further job steps execute.
Adding the when attribute to a job step allows you to override this default behaviour, and selectively run or skip steps depending on the status of the job.
The when attribute accepts the following values:
on_success-
The step runs only if all previous steps succeeded (returned exit code 0).
on_successis the default value. always-
The step runs regardless of the exit status of previous steps. Use
alwayswhen you have a task that must run whether previous steps succeed or fail. For example, you need to upload logs or code-coverage data. on_fail-
The step runs only if one of the preceding steps failed (returns a non-zero exit code). Common uses of
on_failinclude storing diagnostic data to debug test failures, or running custom notifications about the failure, such as sending emails or triggering alerts.
Some steps, such as store_artifacts and store_test_results will always run, even if a step has failed (returned a non-zero exit code) previously. The when attribute, store_artifacts and store_test_results are not run if the job has been killed by a cancel request or has reached the runtime timeout limit.
|
Example:
- run:
name: Upload CodeCov.io Data
command: bash <(curl -s https://codecov.io/bash) -F unittests
when: always # Uploads code coverage results, pass or fail
Ending a job from within a step
A job can exit without failing by using run: circleci-agent step halt. However, if a step within the job is already failing then the job will continue to fail. This can be useful in situations where jobs need to conditionally execute.
Example: halt is used to avoid running a job on the develop branch:
- run: |
if [ "$CIRCLE_BRANCH" = "develop" ]; then
circleci-agent step halt
fi
Automatic step reruns
The following attributes can be used to automatically rerun a step if it fails, and delay that rerun if required:
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Integer |
The maximum number of times to automatically rerun the step if it fails. Must be between |
|
N |
String |
The delay between reruns of the step if it fails. This delay can only be set along with |
Automatic reruns are only supported for run steps, not special steps like checkout or setup_remote_docker.
You must configure the command key for the step, you cannot use the short form run step configuration, for example, the following is not supported for use with automatic reruns: - run: echo "Hello, world!"
Example:
version: 2.1
jobs:
my-job:
steps:
- run:
command: echo "Hello, world!"
max_auto_reruns: 3
auto_rerun_delay: 10s
For more information, see the Automatic Reruns page.
The when step
The when and unless steps are supported in version: 2.1 configuration
|
A conditional step consists of a step with the key when or unless. Under the when key are the subkeys condition and steps. The purpose of the when step is customizing commands and job configuration to run on custom conditions (determined at config-compile time) that are checked before a workflow runs. See the Conditional Steps Section of the Reusable Configuration Reference for more details.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
Logic |
|
|
Y |
Sequence |
A list of steps to execute when the condition is true |
Example:
version: 2.1
jobs: # conditional steps may also be defined in `commands:`
job_with_optional_custom_checkout:
parameters:
custom_checkout:
type: string
default: ""
machine:
image: ubuntu-2004:2024.11.1
steps:
- when:
condition: <<parameters.custom_checkout>>
steps:
- run: echo "my custom checkout"
- unless:
condition: <<parameters.custom_checkout>>
steps:
- checkout
workflows:
build-test-deploy:
jobs:
- job_with_optional_custom_checkout:
custom_checkout: "any non-empty string is truthy"
- job_with_optional_custom_checkout
checkout
A special step used to check out source code to the configured path (defaults to the working_directory). The reason this is a special step is because it is more of a helper function designed to simplify the process of checking out code. If you require doing git over HTTPS you should not use this step as it configures git to checkout over SSH.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
String |
Checkout method. Valid options include |
|
N |
String |
The directory where CircleCI checks out code. CircleCI interprets this relative to the |
If path already exists and is:
-
A git repository - step does not clone whole repository, but rather fetches origin.
-
NOT a git repository - step fails.
In the case of checkout, the step type is just a string with no additional attributes.
Example:
jobs:
build:
docker:
- image: cimg/go:1.24.2
steps:
- checkout
The checkout command automatically adds the required authenticity keys for interacting with GitHub and Bitbucket over SSH. These keys are detailed further in the Integration Guide. This guide is also helpful if you wish to implement a custom checkout command.
You can specify a checkout strategy by using the method key. CircleCI supports full clones or blobless clones. Blobless clones reduce the amount of data fetched from the remote by asking the remote to filter out objects that are not attached to the current commit.
Example:
jobs:
build:
docker:
- image: cimg/go:1.24.2
steps:
- checkout:
method: blobless
|
In certain cases, we will fall back to a full checkout even though blobless was specified. This will occur if Git and SSH clients are not available in the current environment, or if Git version 2.41.0 is installed which contained a known issue for blobless clones. |
If a downstream step requires those objects to exist for scanning or comparisons, a blobless clone can cause failures. In that case, you can specify a full checkout as shown in the following example:
jobs:
build:
docker:
- image: cimg/go:1.24.2
steps:
- checkout:
method: full
CircleCI does not check out submodules. If your project requires submodules, add run steps with appropriate commands as shown in the following example:
jobs:
build:
docker:
- image: cimg/go:1.24.2
steps:
- checkout
- run: git submodule sync
- run: git submodule update --init
The checkout step will configure Git to skip automatic garbage collection. If you are caching your .git directory with restore_cache and would like to use garbage collection to reduce its size, you may wish to use a run step with command git gc before doing so.
|
setup_remote_docker
|
Allows Docker commands to be run locally. See Running Docker Commands for details.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
boolean |
Set this to |
|
N |
String |
Version string of Docker you would like to use (default: |
Example:
jobs:
build:
docker:
- image: cimg/base:2024.06
steps:
# ... steps for building/testing app ...
- setup_remote_docker:
version: default
save_cache
Generates and stores a cache of a file or directory of files such as dependencies or source code. Caches are stored in CircleCI’s object storage. Later jobs can restore this cache. Learn more on the Caching Dependencies page.
Cache retention can be customized on the CircleCI web app by navigating to .
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
List |
List of directories which should be added to the cache |
|
Y |
String |
Unique identifier for this cache |
|
N |
String |
Title of the step to be shown in the CircleCI UI (default: "Saving Cache") |
|
N |
String |
Specify when to enable or disable the step. Takes the following values: |
The cache for a specific key is immutable. If a cache already exists for the given key, CircleCI uses the existing cache and proceeds to the next step.
When storing a new cache, the key value may contain special, templated, values for your convenience:
| Template | Description |
|---|---|
|
The VCS branch currently being built. |
|
The CircleCI build number for this build. |
|
The VCS revision currently being built. |
|
The SSH key used to checkout the repository. |
|
The environment variable |
|
A base64 encoded SHA256 hash of the given filename’s contents. Commit this file to your repository, and reference it as an absolute or relative path from the current working directory. Good candidates are dependency manifests, such as |
|
The current time in seconds since the UNIX epoch. |
|
The OS and CPU information. Useful when caching compiled binaries that depend on OS and CPU architecture, for example, |
During step execution, CircleCI replaces the templates above with runtime values and uses the resultant string as the key.
Template examples:
myapp-{{ checksum "package-lock.json" }}-
CircleCI regenerates the cache every time you change something in the package-lock.json file. Different branches of this project generate the same cache key.
myapp-{{ .Branch }}-{{ checksum "package-lock.json" }}-
Same as the previous one, but each branch generates a separate cache.
myapp-{{ epoch }}-
Every job run generates a separate cache.
While choosing suitable templates for your cache key, keep in mind the following:
-
Cache saving is not a free operation. See the billing section on the FAQ page.
-
It takes time to upload the cache.
-
Best practice is to have a
keythat generates a new cache only if something actually changed and avoid generating a new one every time a job is run. -
Because caches are immutable, start all your cache keys with a version prefix
v1-.... This lets you regenerate all your caches by incrementing the version in this prefix.
Examples:
- save_cache:
key: v1-myapp-{{ arch }}-{{ checksum "project.clj" }}
paths:
- /home/ubuntu/.m2
- save_cache:
key: v1-{{ checksum "yarn.lock" }}
paths:
- node_modules/workspace-a
- node_modules/workspace-c
|
Wildcards are not currently supported in |
restore_cache
Restores a previously saved cache based on a key. Cache needs to have been saved first for this key using the save_cache step. Learn more in The Caching Documentation.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y (1) |
String |
Single cache key to restore |
|
Y (1) |
List |
List of cache keys to check. CircleCI restores the cache from the first existing key. |
|
N |
String |
Title of the step to be shown in the CircleCI UI (default: "Restoring Cache") |
(1) You must specify at least one attribute. If you provide both key and keys, CircleCI checks key first, then keys.
A key is searched against existing keys as a prefix.
| When multiple matches exist, CircleCI uses the most recent match, even if a more precise match exists. |
Example:
steps:
- save_cache:
key: v1-myapp-cache
paths:
- ~/d1
- save_cache:
key: v1-myapp-cache-new
paths:
- ~/d2
- run: rm -f ~/d1 ~/d2
- restore_cache:
key: v1-myapp-cache
In this case, CircleCI restores cache v1-myapp-cache-new because it’s the most recent match with the v1-myapp-cache prefix, even though the first key (v1-myapp-cache) matches exactly.
For more information on key formatting, see the key section of save_cache step.
When CircleCI encounters a list of keys, it restores the cache from the first key that matches an existing cache. We recommend you use a more specific key first (for example, cache for exact version of package-lock.json) and more generic keys after (for example, any cache for this project). If no key matches an existing cache, CircleCI skips the step with a warning.
You don’t need to specify a path here because CircleCI restores the cache to the location where it originally saved it.
Example:
- restore_cache:
keys:
- v1-myapp-{{ arch }}-{{ checksum "project.clj" }}
# if cache for exact version of `project.clj` is not present then load any most recent one
- v1-myapp-
# ... Steps building and testing your application ...
# cache will be saved only once for each version of `project.clj`
- save_cache:
key: v1-myapp-{{ arch }}-{{ checksum "project.clj" }}
paths:
- /foo
deploy - DEPRECATED
See run for current processes. If you have parallelism > 1 in your job, see the Migrate From Deploy to Run guide.
store_artifacts
Step to store artifacts (for example logs, binaries, etc) to be available in the web app or through the API. See the Uploading Artifacts page for more information.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
Directory in the primary container to save as job artifacts |
|
N |
String |
Prefix added to the artifact paths in the artifacts API (default: the directory of the file specified in |
There can be multiple store_artifacts steps in a job. Using a unique prefix for each step prevents them from overwriting files.
Artifact storage retention can be customized on the CircleCI web app by navigating to .
Example:
- run:
name: Build the Jekyll site
command: bundle exec jekyll build --source jekyll --destination jekyll/_site/docs/
- store_artifacts:
path: jekyll/_site/docs/
destination: circleci-docs
store_test_results
Special step used to upload and store test results for a build. Test results are visible on the CircleCI web application under each build’s Test Summary section. Storing test results is useful for timing analysis of your test suites. For more information on storing test results, see the Collecting Test Data page.
You can also store test results as build artifacts. For steps, refer to the store_artifacts step section.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
Path (absolute, or relative to your |
Example:
Directory structure:
test-results
├── jest
│ └── results.xml
├── mocha
│ └── results.xml
└── rspec
└── results.xml
config.yml syntax:
- store_test_results:
path: test-results
persist_to_workspace
Special step used to persist a temporary file to be used by another job in the workflow. For more information on using workspaces, see the Using Workspaces to Share Data Between Jobs page.
persist_to_workspace adopts the storage settings from the storage customization controls on the CircleCI web app. If no custom setting is provided, persist_to_workspace defaults to 15 days.
Workspace storage retention can be customized on the CircleCI web app by navigating to .
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
Either an absolute path or a path relative to |
|
Y |
List |
Glob identifying file(s), or a non-glob path to a directory to add to the shared workspace. Interpreted as relative to the workspace root. Must not be the workspace root itself. |
The root key is a directory on the container which is taken to be the root directory of the workspace. The path values are all relative to the root.
Example for root Key:
For example, the following step syntax persists the specified paths from /tmp/dir into the workspace, relative to the directory /tmp/dir.
- persist_to_workspace:
root: /tmp/dir
paths:
- foo/bar
- baz
After this step completes, the following directories are added to the workspace:
/tmp/dir/foo/bar /tmp/dir/baz
Example for paths Key:
- persist_to_workspace:
root: /tmp/workspace
paths:
- target/application.jar
- build/*
The paths list uses Glob from Go, and the pattern matches filepath.Match.
pattern:
{ term }
term:
'*' matches any sequence of non-Separator characters
'?' matches any single non-Separator character
'[' [ '^' ] { character-range }
']' character class (must be non-empty)
c matches character c (c != '*', '?', '\\', '[')
'\\' c matches character c
character-range:
c matches character c (c != '\\', '-', ']')
'\\' c matches character c
lo '-' hi matches character c for lo <= c <= hi
The Go documentation states that the pattern may describe hierarchical names such as /usr/*/bin/ed (assuming the Separator is '/').
| Everything must be relative to the work space root directory. |
attach_workspace
Special step used to attach the workflow’s workspace to the current container. The full contents of the workspace are downloaded and copied into the directory the workspace is being attached at. For more information on using workspaces, see the Using Workspaces page.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
Directory to attach the workspace to. |
Workspace storage retention can be customized on the CircleCI web app by navigating to .
Example:
- attach_workspace:
at: /tmp/workspace
| The lifetime of artifacts, workspaces, and caches can be customized on the CircleCI web app by navigating to . Here you can control the storage retention periods for these objects. If no storage period is set, the default storage retention period of artifacts is 30 days, while the default storage retention period of workspaces and caches is 15 days. |
add_ssh_keys
Special step that adds SSH keys from a project’s settings to a container. Also configures SSH to use these keys. For more information on SSH keys see the Add Additional SSH Keys page.
| Using server? CircleCI Server supports only MD5 fingerprints. You can see the MD5 fingerprint in CircleCI under . An upcoming server release is planned to include SHA256 support. |
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
List |
List of fingerprints corresponding to the keys to be added (default: all keys added) |
steps:
- add_ssh_keys:
fingerprints:
- "b7:35:a6:4e:9b:0d:6d:d4:78:1e:9a:97:2a:66:6b:be"
- "SHA256:NPj4IcXxqQEKGXOghi/QbG2sohoNfvZ30JwCcdSSNM0"
Even though CircleCI uses ssh-agent to sign all added SSH keys, you must use the add_ssh_keys key to actually add keys to a container.
|
Using pipeline values
Pipeline values are available to all pipeline configurations and can be used without previous declaration. For a list of pipeline values, see the Pipeline Values and Parameters page.
Example:
version: 2.1
jobs:
build:
docker:
- image: cimg/node:20.18.1
environment:
IMAGETAG: latest
working_directory: ~/main
steps:
- run: echo "This is pipeline ID << pipeline.id >>"
circleci_ip_ranges
| A paid account on a Performance or Scale Plan is required to access IP ranges. |
Enables jobs to go through a set of well-defined IP address ranges. See IP Ranges for details.
Example:
version: 2.1
jobs:
build:
circleci_ip_ranges: true # opts the job into the IP ranges feature
docker:
- image: curlimages/curl
steps:
- run: echo “Hello World”
workflows:
build-workflow:
jobs:
- build
workflows
Used for orchestrating all jobs. Each workflow consists of the workflow name as a key and a map as a value. A name should be unique within the current config.yml. The top-level keys for the Workflows configuration are version and jobs. For more information, see the Using Workflows to Orchestrate Jobs page.
version
The workflows version key is not required for version: 2.1 configuration
|
The Workflows version field is used to issue warnings for deprecation or breaking changes.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y if config version is |
String |
Should currently be |
workflows:
version: 2
my-workflow:
jobs:
- my-job
max_auto_reruns
The max_auto_reruns key is used to configure the maximum number of automatic reruns for a workflow.
version: 2.1
workflows:
my-workflow:
max_auto_reruns: 3
jobs:
- build
- test
- deploy:
requires:
- build
- test
The value of max_auto_reruns can be an integer between 1 and 5.
For more information, see the Automatic Reruns page.
triggers
Specifies which triggers will cause this workflow to be executed. Default behavior is to trigger the workflow when pushing to a branch.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Array |
Should currently be |
workflows:
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- main
- beta
jobs:
- test
schedule
| Scheduled workflows are not available for projects integrated through the GitHub App, GitLab or Bitbucket Data Center. |
| Using schedule triggers rather than scheduled workflows offers several benefits. Visit the schedule triggers Migration Guide to find out how to migrate existing scheduled workflows to schedule triggers. If you would like to set up schedule triggers from scratch, visit the Schedule Triggers page. |
A workflow may have a schedule indicating it runs at a certain time, for example a nightly build that runs every day at 12am UTC:
workflows:
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- main
- beta
jobs:
- test
cron
The cron key is defined using POSIX crontab syntax.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
String |
See the |
workflows:
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- main
- beta
jobs:
- test
filters
Trigger filters can have the key branches.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
Map |
A map defining rules for execution on specific branches |
workflows:
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- main
- beta
jobs:
- test
branches
The branches key controls whether the current branch should have a schedule trigger created for it, where current branch is the branch containing the config.yml file with the trigger stanza. That is, a push on the main branch will only schedule a workflow using Filters in Your Workflows for the main branch.
Branches can have the keys only and ignore which each map to a single string naming a branch. You may also use regular expressions to match against branches by enclosing them with `/’s, or map to a list of such strings. Regular expressions must match the entire string.
-
The job runs on any branches that match
only. -
The job does not run on any branches that match
ignore. -
If you specify neither
onlynorignore, the job runs on all branches. If you specify bothonlyandignore, CircleCI usesonlyand ignoresignore.
workflows:
commit:
jobs:
- test
- deploy
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- main
- /^release\/.*/
jobs:
- coverage
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
Map |
A map defining rules for execution on specific branches |
|
N |
String, or List of Strings |
Either a single branch specifier, or a list of branch specifiers |
|
N |
String, or List of Strings |
Either a single branch specifier, or a list of branch specifiers |
1: One of either only or ignore branch filters must be specified. If both are present, only is used.
Using when in workflows
Using when or unless under workflows is supported in version: 2.1 configuration. Workflows are always run unless there is a when or unless filter that prevents the workflow from being run. If you want a workflow to run in every pipeline, do not add a when or unless filter.
|
You may use a when clause (the inverse clause unless is also supported) under a workflow declaration with a logic statement to determine whether or not to run that workflow.
The example configuration below uses a pipeline parameter, run_integration_tests to drive the integration_tests workflow.
version: 2.1
workflows:
integration_tests:
when: pipeline.git.branch == "main"
jobs:
- mytestjob
jobs:
...
This example prevents the workflow integration_tests from running unless the pipeline is triggered on the main branch.
Refer to the Workflows for more examples and conceptual information.
jobs
A job can have the keys requires, name, context, type, and filters.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
List |
A list of jobs to run with their dependencies |
<job_name>
A job name that exists in your config.yml.
version: 2.1
jobs:
my-job:
docker:
- image: cimg/node:20.18.1
steps:
- run: echo "Hello World"
workflows:
my-workflow:
jobs:
- my-job
override-with
The override-with key is used to override the job configuration with a job from the referenced orb. For more information, see the How to Override Config page.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
String |
The orb job name you use to override the existing job configuration. (Supports both URL-based and registry orbs) |
Example:
version: 2.1
orbs:
my-orb: << url-ref >>
jobs:
build:
steps:
- run: task build
test:
steps:
- run: task test
deploy:
steps:
- run: ccc deploy
workflows:
- build-test-deploy:
jobs:
- build
- test:
override-with: my-orb/my-test
requires: build
- deploy:
requires: test
In the example above, the test job in the workflow is being overridden with the orb job my-orb/my-test. The my-orb/my-test job might be defined with a different resource class or execution steps.
If the my-orb/my-test job is not defined inside the orb, the test job will compile using the local job definition.
serial-group
The serial-group key is used to add a property to a job to allow a group of jobs to run in series, rather than concurrently, across an organization. Serial groups control the orchestration of jobs across an organization, not just within projects and pipelines.
The serial-group key is configurable per job. It is not possible to configure the key for a group of jobs at this time.
The value of the serial-group key is a string that is used to group jobs together to run one after another. The key must meet the following requirements:
-
Must be less than or equal to (≤) 512 characters, once compiled.
-
Must not be blank.
-
Must consist of alphanumeric characters plus,
.,-,_,/.
Note the following features of serial groups:
-
You can use pipeline values and parameters in the
serial-groupkey. -
Serial groups wait for five hours. After this time, CircleCI cancels any jobs still waiting in the group. This does not affect the standard limits that apply to a job’s runtime.
|
Pipeline order protection in serial groups Jobs in a serial group follow an order protection mechanism, as follows:
If there are no serial groups waiting/running, a pipeline with a lower number can start, such as restoring back to a previous pipeline via a rerun workflow. |
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
String |
A string that is used across an org to group jobs together to run one after another. Can include pipeline values and parameters. Use this same serial group across multiple pipelines to control the orchestration of jobs across an organization. |
Example:
# Creating multiple pipelines at the same time with the below config will results in
# all pipelines running test and build but only a single pipeline will run deploy at a time.
workflows:
main-workflow:
jobs:
- test
- build
- deploy:
serial-group: << pipeline.project.slug >>/deploy-group
requires:
- test
- build
For more information, see the Controlling Serial Execution Across Your Organization page.
requires
Jobs are run concurrently by default, so you must explicitly require any dependencies by their job name if you need some jobs to run sequentially.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
List |
A list of jobs that must succeed a specified status before the job starts. Note: When jobs you list as dependencies don’t execute (due to filters, for example), CircleCI ignores them as dependencies for other jobs. However, if all dependencies of a job are filtered, that job doesn’t execute either. Possible types of
The possible status values are: |
workflows:
my-workflow:
jobs:
- build
- test:
requires:
- build
- deploy:
requires:
- build
- test
- notify-build-canceled:
requires:
- build: canceled
- cleanup:
requires:
- deploy:
- failed
- canceled
name
The name key can be used to invoke reusable jobs across any number of workflows. Using the name key ensures numbers are not appended to your job name (for example, sayhello-1 , sayhello-2, etc.). The name you assign to the name key needs to be unique, otherwise the numbers will still be appended to the job name.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
String |
A replacement for the job name. Useful when calling a job multiple times. If you want to invoke the same job multiple times, and a job requires one of the duplicate jobs, this key is required. (2.1 only) |
workflows:
my-workflow:
jobs:
- my-job:
name: my-alternative-job-name
context
Jobs may be configured to use global environment variables set for an organization, see the Contexts document for adding a context in the application settings.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
String/List |
The name of the context(s). The initial default name is |
workflows:
my-workflow:
jobs:
- my-job:
context: org-global
It is also possible to use a list of contexts, as follows:
workflows:
my-workflow:
jobs:
- my-job:
context:
- org-global
- project-global
You can also use an expression to determine the contexts for a job:
workflows:
my-workflow:
jobs:
- my-job:
context: << pipeline.git.branch == "main" and "org-global" or "project-global" >>
type
A job may have a type of approval indicating it must be manually approved before downstream jobs may proceed. For more information see the Using Workflows to Orchestrate Jobs page.
Jobs run in the dependency order until the workflow processes a job with the type: approval key followed by a job on which it depends, for example:
workflows:
my-workflow:
jobs:
- build
- test:
requires:
- build
- hold:
type: approval
requires:
- test
- deploy:
requires:
- hold
An approval job can have any name. In the example above the approval job is named hold. The name you choose for an approval job should not be used to define a job in the main configuration. An approval job only exists as a workflow orchestration devise.
filters
Filter job execution within a workflow based on the following:
-
Branch
-
Tag
-
Expression-based condition
Job filters can have the keys branches or tags.
Workflows will ignore job-level branching. If you use job-level branching and later add workflows, you must remove the branching at the job level and instead declare it in the workflows section of your config.yml.
|
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Map |
A map or string to define rules for job execution. Branch and tag filters require a map. Expression-based filters require a string. |
The following is an example of how the CircleCI documentation project uses a regular expression to filter running a job in a workflow only on a specific branch:
# ...
workflows:
build-deploy:
jobs:
- js_build
- build_server_pdfs: # << the job to conditionally run based on the filter-by-branch-name.
filters:
branches:
only: /server\/.*/ # the job build_server_pdfs will only run when the branch being built starts with server/
You can read more about using regular expressions in your config in the Using Workflows to Schedule Jobs page.
Expression-based job filters
Expression-based job filters allow you to conditionally run jobs based on the following:
An expression-based job filter is a rule that is evaluated against pipeline values and parameters to decide whether a job should run.
Using expression-based job filters is one way to optimize your pipelines. Optimizations include the following:
-
Lower costs.
-
Decrease time to feedback.
-
Run specific jobs based on the context of the source of change.
workflows:
deploy:
jobs:
- init-service
- test-service
- build-service-image:
requires:
- init-service
- dry-run-service:
requires:
- init-service
filters: pipeline.git.branch != "main" and pipeline.git.branch != "canary"
- publish-service:
requires:
- build-service-image
- test-service
filters: pipeline.git.branch == "main" or pipeline.git.tag starts-with "release"
- deploy-service:
context:
- org-global
requires:
- publish-service
filters: pipeline.git.branch == "main" and pipeline.parameters.my-custom-param starts-with "DEPLOY:"
Examples:
Only run the job on the project’s main branch:
filters: pipeline.git.branch == "main"
Only run the job on the project’s main branch, or branches starting with integration-test:
filters: pipeline.git.branch == "main" or pipeline.git.branch starts-with "integration-test"
Only run the job on the main branch, and disallow use with pipelines Triggered With Unversioned Configuration:
filters: pipeline.git.branch == "main" and not (pipeline.trigger_source starts-with "api")
Use pipeline parameters and the pipeline value pipeline.git.branch to run a job only on specific branches or when triggered via the API with a pipeline parameter set to true:
version: 2.1
parameters:
run-storybook-tests:
type: boolean
default: false
...
# jobs configuration omitted for brevity
workflows:
build:
jobs:
- setup
- storybook-tests:
requires:
- setup
filters: |
pipeline.parameters.run-storybook-tests
or pipeline.git.branch == "dry-run-deploy"
or pipeline.git.branch starts-with "deploy"
You can use the API to trigger a pipeline with a pipeline parameter set to true:
Using server? If you are using CircleCI server, replace https://circleci.com with your server hostname when interacting with the CircleCI API.
|
curl -X POST https://circleci.com/api/v2/project/circleci/<org-id>/<project-id>/pipeline/run \
--header "Circle-Token: $CIRCLE_TOKEN" \
--header "content-type: application/json" \
--data {
"definition_id": "<pipeline-definition-id>",
"config": {"branch": "<your-branch-name>"},
"checkout": {"branch": "<your-branch-name>"},
"parameters": {"run-storybook-tests": "true"}
}
Operators
The operators you can use for expression-based job filters are described in the following table. You can also group sub-expressions with parentheses (, ). as in the examples above.
| Operator type | Operators | Description |
|---|---|---|
Logical |
|
These are short-circuiting boolean operators. |
Equality |
|
String, numeric, and boolean equality. If the operands are of different types then |
Equality |
|
String prefix equality, |
Numeric comparison |
|
Numeric comparisons. It is an error to use a non-numeric type as an operand. |
Negation |
|
Boolean negation. Note that
|
branches
The branches filter can have the keys only and ignore, which map to a single string naming a branch. You may also use regular expressions to match against branches by enclosing them with slashes, or map to a list of such strings. Regular expressions must match the entire string.
-
Any branches that match
onlywill run the job. -
Any branches that match
ignorewill not run the job. -
If you specify neither
onlynorignore, the job runs on all branches. -
If you specify both
onlyandignore, CircleCI checksonlybeforeignore.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Map |
A map defining rules for execution on specific branches. |
|
N |
String, or list of strings |
Either a single branch specifier, or a list of branch specifiers. |
|
N |
String, or list of strings |
Either a single branch specifier, or a list of branch specifiers. |
workflows:
dev_stage_pre-prod:
jobs:
- test_dev:
filters: # using regex filters requires the entire branch to match
branches:
only: # only branches matching the below regex filters will run
- dev
- /user-.*/
- test_stage:
filters:
branches:
only: stage
- test_pre-prod:
filters:
branches:
only: /pre-prod(?:-.+)?$/
tags
CircleCI does not run workflows for tags unless you explicitly specify tag filters. If a job requires any other jobs (directly or indirectly), you must specify tag filters for those jobs.
Tags can have the keys only and ignore. You may also use regular expressions to match against tags by enclosing them with slashes, or map to a list of such strings. Regular expressions must match the entire string. Both lightweight and annotated tags are supported.
-
Any tags that match
onlyruns the job. -
Any tags that match
ignoredoes not run the job. -
If neither
onlynorignoreare specified then the job is skipped for all tags. -
If both
onlyandignoreare specified theonlyis considered beforeignore.
| Key | Required | Type | Description |
|---|---|---|---|
|
N |
Map |
A map defining rules for execution on specific tags |
|
N |
String, or List of Strings |
Either a single tag specifier, or a list of tag specifiers |
|
N |
String, or List of Strings |
Either a single tag specifier, or a list of tag specifiers |
For more information, see the Executing Workflows for a Git Tag section of the Workflows page.
workflows:
untagged-build:
jobs:
- build
tagged-build:
jobs:
- build:
filters:
tags:
only: /^v.*/
matrix
The matrix key is supported in version: 2.1 configuration
|
The matrix stanza allows you to run a parameterized job multiple times with different arguments. For more information see the how-to guide on Using Matrix Jobs. In order to use the matrix stanza, you must use parameterized jobs.
| Key | Required | Type | Description |
|---|---|---|---|
|
Y |
Map |
A map of parameter names to every value the job should be called with |
|
N |
List |
A list of argument maps that should be excluded from the matrix |
|
N |
String |
An alias for the matrix, usable from another job’s |
Example:
The following is a basic example of using matrix jobs.
workflows:
workflow:
jobs:
- build:
matrix:
parameters:
version: ["0.1", "0.2", "0.3"]
platform: ["macos", "windows", "linux"]
This expands to 9 different build jobs, and could be equivalently written as:
workflows:
workflow:
jobs:
- build:
name: build-macos-0.1
version: "0.1"
platform: macos
- build:
name: build-macos-0.2
version: "0.2"
platform: macos
- build:
name: build-macos-0.3
version: "0.3"
platform: macos
- build:
name: build-windows-0.1
version: "0.1"
platform: windows
- ...
Excluding sets of parameters from a matrix
Sometimes you may wish to run a job with every combination of arguments except
some value or values. You can use an exclude stanza to achieve this:
workflows:
workflow:
jobs:
- build:
matrix:
parameters:
a: [1, 2, 3]
b: [4, 5, 6]
exclude:
- a: 3
b: 5
The matrix above would expand into 8 jobs: every combination of the parameters
a and b, excluding {a: 3, b: 5}
Dependencies and matrix jobs
To require an entire matrix (every job within the matrix), use its alias.
The alias defaults to the name of the job being invoked.
workflows:
workflow:
jobs:
- deploy:
matrix:
parameters:
version: ["0.1", "0.2"]
- another-job:
requires:
- deploy
This means that another-job will require both deploy jobs in the matrix to
finish before it runs.
Matrix jobs expose their parameter values via << matrix.* >>
which can be used to generate more complex workflows. For example, here is a
deploy matrix where each job waits for its respective build job in another
matrix.
workflows:
workflow:
jobs:
- build:
name: build-v<< matrix.version >>
matrix:
parameters:
version: ["0.1", "0.2"]
- deploy:
name: deploy-v<< matrix.version >>
matrix:
parameters:
version: ["0.1", "0.2"]
requires:
- build-v<< matrix.version >>
This workflow expands to:
workflows:
workflow:
jobs:
- build:
name: build-v0.1
version: "0.1"
- build:
name: build-v0.2
version: "0.2"
- deploy:
name: deploy-v0.1
version: "0.1"
requires:
- build-v0.1
- deploy:
name: deploy-v0.2
version: "0.2"
requires:
- build-v0.2
pre-steps and post-steps
Pre-steps and post-steps are supported in version: 2.1 configuration
|
Every job invocation in a workflow may optionally accept two special arguments: pre-steps and post-steps.
Steps under pre-steps are executed before any of the other steps in the job. The steps under post-steps are executed after all of the other steps.
Pre and post steps allow you to execute steps in a given job without modifying the job. Pre and post steps are useful, for example, to run custom setup steps before job execution.
version: 2.1
jobs:
bar:
machine:
image: ubuntu-2004:2024.05.1
steps:
- checkout
- run:
command: echo "building"
- run:
command: echo "testing"
workflows:
build:
jobs:
- bar:
pre-steps: # steps to run before steps defined in the job bar
- run:
command: echo "install custom dependency"
post-steps: # steps to run after steps defined in the job bar
- run:
command: echo "upload artifact to s3"
Logic statements
Certain dynamic configuration features accept logic statements as arguments. Logic statements are evaluated to boolean values at configuration compilation time, that is, before the workflow is run. The group of logic statements includes:
| Type | Arguments | true if |
Example |
|---|---|---|---|
YAML literal |
None |
is truthy |
|
None |
resolves to a truthy value |
|
|
None |
resolves to a truthy value |
|
|
|
N logic statements |
all arguments are truthy |
|
|
N logic statements |
any argument is truthy |
|
|
1 logic statement |
the argument is not truthy |
|
|
N values |
all arguments evaluate to equal values |
|
|
|
|
|
The following logic values are considered falsy:
-
false.
-
null.
-
0
-
NaN
-
empty strings ("").
-
statements with no arguments.
All other values are truthy. Also note that using logic with an empty list will cause a validation error.
Logic statements always evaluate to a boolean value at the top level, and coerce as necessary. They can be nested in an arbitrary fashion, according to their argument specifications, and to a maximum depth of 100 levels.
matches uses Java regular
expressions
for its pattern. A full match pattern must be provided, prefix matching is not an option. Though, it is recommended to enclose a pattern in ^ and
$ to avoid accidental partial matches.
When using logic statements at the workflow level, do not include the condition: key (the condition key is only needed for job level logic statements).
|
Example:
workflows:
my-workflow:
when:
or:
- equal: [ main, << pipeline.git.branch >> ]
- equal: [ staging, << pipeline.git.branch >> ]
Using expressions in your configuration
CircleCI configuration supports expressions for dynamic value evaluation. Expressions can include pipeline values, pipeline parameters, literals, and operators such as and, or, and comparison operators.
Expressions in configuration fields
Configuration fields accept expressions either directly or as string values. When you provide a string value, you can use << >> delimiters to mark a section of the string that should be interpreted as an expression.
You can write the expression in a configuration field as shown in the following example:
jobs:
test:
docker:
- image: cimg/base:current
parallelism: << pipeline.git.branch == "main" and 10 or 1 >>
steps:
- checkout
- run: run_tests
In this example, parallelism is set to 10 when running on the main branch, and 1 on all other branches.
Use direct expressions in job filters and using when or unless in your workflows. For example:
workflows:
my-workflow:
jobs:
- build:
filters: pipeline.git.branch == "main" or pipeline.git.branch starts-with "release/"
when expressionworkflows:
deploy-workflow:
when: pipeline.git.tag starts-with "v" and pipeline.trigger_source == "webhook"
jobs:
- deploy
For all other configuration fields, you must use the << >> delimiters to mark the expression as an expression, as shown in other examples in this section.
Expressions within strings
When you need to include an expression within a larger string value, use << >> delimiters to mark the expression:
- run:
name: Print branch info
command: |
echo "Running on << pipeline.git.branch or "unknown branch" >>"
In this example, the << >> delimiters mark pipeline.git.branch or "unknown branch" as an expression. If pipeline.git.branch is null (for example, when the pipeline is triggered for a tag rather than a branch), the or operator provides the fallback value "unknown branch".
Conditional logic example
You can combine and and or to implement if-then-else style logic:
parallelism: << pipeline.git.branch == "main" and 10 or 1 >>
-
If the condition
pipeline.git.branch == "main"is true, theandexpression evaluates to its second operand10. -
If the condition is false, the
andexpression evaluates to false, and theorexpression returns the fallback value1.
Expression operators
The operators you can use for expressions are described in the following table. You can also group sub-expressions with parentheses (, ).
| Operator type | Operators | Description |
|---|---|---|
Logical |
|
These are short-circuiting boolean operators. |
Equality |
|
String, numeric, and boolean equality. If the operands are of different types then |
Equality |
|
String prefix equality, |
Numeric comparison |
|
Numeric comparisons. It is an error to use a non-numeric type as an operand. |
Negation |
|
Boolean negation. Note that
|
Valid parameter names
To use a pipeline parameter in an expression, the parameter name must follow these rules:
-
Start with a letter.
-
Can contain upper-case letters (
A-Z) and lower-case letters (a-z). -
Can contain digits (
0-9). -
Can contain hyphens (
-), underscores (_), and periods (.). -
Cannot contain consecutive periods (
..).
|
If a pipeline parameter has a name that does not follow these rules, CircleCI performs string replacement instead of evaluating an expression. |
Logic statement and expression examples
You can find usage examples on the Orchestration Cookbook page.
Example full configuration
| Using Docker? Authenticating Docker pulls from image registries is recommended when using the Docker execution environment. Authenticated pulls allow access to private Docker images, and may also grant higher rate limits, depending on your registry provider. For further information see Using Docker authenticated pulls. |
version: 2.1
jobs:
build:
docker:
- image: ubuntu:23.04
- image: mongo:6.0.14
command: [mongod, --smallfiles]
- image: postgres:14.12
# some containers require setting environment variables
environment:
POSTGRES_USER: user
- image: redis@sha256:54057dd7e125ca41afe526a877e8bd35ec2cdd33b9217e022ed37bdcf7d09673
- image: rabbitmq:3.12.12
environment:
TEST_REPORTS: /tmp/test-reports
working_directory: ~/my-project
steps:
- checkout
- run:
command: echo 127.0.0.1 devhost | sudo tee -a /etc/hosts
# Create Postgres users and database
# Note the YAML heredoc '|' for nicer formatting
- run: |
sudo -u root createuser -h localhost --superuser ubuntu &&
sudo createdb -h localhost test_db
- restore_cache:
keys:
- v1-my-project-{{ checksum "project.clj" }}
- v1-my-project-
- run:
environment:
SSH_TARGET: "localhost"
TEST_ENV: "linux"
command: |
set -xu
mkdir -p ${TEST_REPORTS}
run-tests.sh
cp out/tests/*.xml ${TEST_REPORTS}
- run: |
set -xu
mkdir -p /tmp/artifacts
create_jars.sh << pipeline.number >>
cp *.jar /tmp/artifacts
- save_cache:
key: v1-my-project-{{ checksum "project.clj" }}
paths:
- ~/.m2
# Save artifacts
- store_artifacts:
path: /tmp/artifacts
destination: build
# Upload test results
- store_test_results:
path: /tmp/test-reports
deploy-stage:
docker:
- image: ubuntu:23.04
working_directory: /tmp/my-project
steps:
- run:
name: Deploy if tests pass and branch is Staging
command: ansible-playbook site.yml -i staging
deploy-prod:
docker:
- image: ubuntu:23.04
working_directory: /tmp/my-project
steps:
- run:
name: Deploy if tests pass and branch is Main
command: ansible-playbook site.yml -i production
workflows:
build-deploy:
jobs:
- build:
filters:
branches:
ignore:
- develop
- /feature-.*/
- deploy-stage:
requires:
- build
filters:
branches:
only: staging
- deploy-prod:
requires:
- build
filters:
branches:
only: main