# 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](#example-full-configuration).

* * *

## **`version`**

The `version` field is intended to be used in order to issue warnings for deprecation or breaking changes.

   

Key

Required

Type

Description

`version`

Y

String

`2`, `2.0`, or `2.1` See the [Reusable Configuration](https://circleci.com/docs/reference/reusing-config/) page for an overview of 2.1 keys available to simplify your `.circleci/config.yml` file, reuse, and parameterized jobs.

**Example:**

Version

`````````
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

`setup`

N

Boolean

Designates the `config.yaml` for use of CircleCI’s [Dynamic Configuration](https://circleci.com/docs/guides/orchestrate/dynamic-config/) feature.

**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

`orbs`

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](https://circleci.com/docs/orbs/author/create-test-and-publish-a-registry-orb/) documentation for details.

`executors`

N

Map

A map of strings to executor definitions. See the [**`executors`**](#executors) section below.

`commands`

N

Map

A map of command names to command definitions. See the [**`commands`**](#commands) section below.

The following example uses the `node` orb that exists in the certified `circleci` namespace. Refer to the Node orb page in the [Orb Registry](https://circleci.com/developer/orbs/orb/circleci/node) 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:

*   [Using Orbs](https://circleci.com/docs/orbs/use/orb-intro/).
    
*   [Authoring Orbs](https://circleci.com/docs/orbs/author/orb-author/).
    

Public orbs are listed in the [Orb Registry](https://circleci.com/developer/orbs).

* * *

## **`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](https://circleci.com/docs/reference/reusing-config/).

   

Key

Required

Type

Description

`steps`

Y

Sequence

A sequence of steps run inside the calling job of the command.

`parameters`

N

Map

A map of parameter keys. See the [Parameter Syntax](https://circleci.com/docs/reference/reusing-config/#parameter-syntax) section of the [Reusing Config](https://circleci.com/docs/reference/reusing-config/) document for details.

`description`

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](https://circleci.com/docs/guides/orchestrate/pipeline-variables/#pipeline-parameters-in-configuration) for usage details.

   

Key

Required

Type

Description

`parameters`

N

Map

A map of parameter keys. Supports `string`, `boolean`, `integer` and `enum` types. See [Parameter Syntax](https://circleci.com/docs/reference/reusing-config/#parameter-syntax) for details.

**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

`docker`

Y (1)

List

Options for [Docker executor](#docker)

`resource_class`

N

String

Amount of CPU and RAM allocated to each container in a job.

`machine`

Y (1)

Map

Options for [machine executor](#machine)

`macos`

Y (1)

Map

Options for [macOS executor](#macos)

`windows`

Y (1)

Map

[Windows executor](#windows-execution-environment) currently working with orbs. Check out [the orb](https://circleci.com/developer/orbs/orb/circleci/windows).

`shell`

N

String

Shell to use for execution command in all steps. Can be overridden by `shell` in each step (default: See [Default Shell Options](#default-shell-options))

`working_directory`

N

String

The directory where steps run. CircleCI interprets this as an absolute path.

`environment`

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](https://circleci.com/docs/reference/reusing-config/#using-parameters-in-executors) section of the [Reusing Config](https://circleci.com/docs/reference/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](https://circleci.com/docs/guides/toolkit/sample-config/) 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`**](#resourceclass).
    
*   Using [Parallelism](https://circleci.com/docs/guides/optimize/parallelism-faster-jobs/).
    
*   Run some of your jobs concurrently using [Workflows](https://circleci.com/docs/guides/orchestrate/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

`type`

N

String

Job type, can be `build`, `release`, `no-op`, or `approval`. If not specified, defaults to `build`.

`docker`

Y (1)

List

Options for the [Docker executor](#docker)

`machine`

Y (1)

Map

Options for the [machine executor](#machine)

`macos`

Y (1)

Map

Options for the [macOS executor](#macos)

`executor`

Y (1)

String

Name of a declared [reusable executor](#executors)

`shell`

N

String

Shell to use for execution command in all steps. Can be overridden by `shell` in each step (default: See [Default Shell Options](#default-shell-options))

`parameters`

N

Map

[Parameters](#parameters-job) for making a `job` explicitly configurable in a `workflow`.

`steps`

Y

List

A list of [steps](#steps) to be performed

`working_directory`

N

String

The directory where steps run. CircleCI interprets this as an absolute path. Default: `~/project` (where `project` is a literal string, not your specific project name). Processes running during the job can use the `$CIRCLE_WORKING_DIRECTORY` environment variable to refer to this directory. **Note:** CircleCI does not expand paths in your YAML configuration file; if your `store_test_results.path` is `$CIRCLE_WORKING_DIRECTORY/tests`, CircleCI attempts to store the `test` subdirectory of the directory literally named `$CIRCLE_WORKING_DIRECTORY`, including the dollar sign `$`. CircleCI creates `working_directory` automatically if it doesn’t exist.

`parallelism`

N

Integer

Number of parallel instances of this job to run (default: 1)

`environment`

N

Map

A map of environment variable names and values.

`branches`

N

Map

This key is deprecated. Use [workflows filtering](#jobfilters) to control which jobs run for which branches.

`resource_class`

N

String

Amount of CPU and RAM allocated to each container in a job.

`retention`

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](https://circleci.com/docs/guides/deploy/configure-your-kubernetes-components/#link-release) to a deployment in the CircleCI deploys UI. For full details, see the [Deploys Overview](https://circleci.com/docs/guides/deploy/deployment-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](https://circleci.com/docs/guides/orchestrate/orchestration-cookbook/#use-no-op-jobs-to-create-a-cleaner-workflow-graph)

**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](#type) 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](https://circleci.com/docs/guides/security/env-vars/) 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](https://circleci.com/docs/guides/optimize/persist-data/#custom-storage-usage) 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 `retention` key expects a map with `caches` as a string value, not a direct string.
    

**Examples:**

Incorrect - direct string value

`````````
# Incorrect - direct string value
jobs:
  say-hello:
    retention: "12h"  # Error: expected type: String, found: Mapping
`````````

Incorrect - invalid time format

`````````
#Incorrect - invalid time format
jobs:
  say-hello:
    retention:
      caches: "12h"  # Error: does not match pattern ^([1-9]|[12][0-9]|30)d$
`````````

Correct format

`````````
# 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](https://circleci.com/docs/guides/optimize/parallelism-faster-jobs/) page.
    
*   Refer to the [Use the CircleCI CLI to Split Tests](https://circleci.com/docs/guides/optimize/use-the-circleci-cli-to-split-tests/) how-to guide.
    
*   Follow the [Test Splitting Tutorial](https://circleci.com/docs/guides/test/test-splitting-tutorial/).
    

**Use an integer:**

`````````
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
`````````

**Use an expression:**

`````````
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`](#jobs-in-workflow).

Reserved parameter-names:

*   `name`
    
*   `requires`
    
*   `context`
    
*   `type`
    
*   `filters`
    
*   `matrix`
    

See [Parameter Syntax](https://circleci.com/docs/reference/reusing-config/#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](https://circleci.com/docs/guides/execution-managed/executor-intro/).

* * *

### `docker`

Configure a job to use the Docker execution environment using the `docker` key which takes a list of maps:

   

Key

Required

Type

Description

`image`

Y

String

The name of a custom Docker image to use. The first `image` listed under a job defines the job’s own primary container image where all steps will run.

`name`

N

String

`name` defines the hostname for the container (the default is `localhost`), which is used for reaching secondary (service) containers. By default, all services are exposed directly on `localhost`. This field is useful if you would rather have a different hostname instead of `localhost`, for example, if you are starting multiple versions of the same service.

`entrypoint`

N

String or List

The command used as executable when launching the container. `entrypoint` overrides the image’s [`ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint).

`command`

N

String or List

The command to use as PID 1 (or as arguments for entrypoint) when launching the container. `command` overrides the image’s `COMMAND`. If the image has an `ENTRYPOINT`, Docker uses `command` as arguments to it. If the image has no `ENTRYPOINT`, Docker uses `command` as the executable.

`user`

N

String

Which user to run commands as within the Docker container

`environment`

N

Map

A map of environment variable names and values. The `environment` settings apply to the entrypoint/command run by the Docker container, not the job steps.

`auth`

N

Map

Authentication for registries using standard `docker login` credentials

`aws_auth`

N

Map

Authentication for AWS Elastic Container Registry (ECR)

`gcp_auth`

N

Map

Authentication for GCP Artifact Registry using OIDC

For a [Primary Container](https://circleci.com/docs/reference/glossary/#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](https://circleci.com/docs/guides/execution-managed/custom-images/#adding-an-entrypoint) 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](https://circleci.com/docs/guides/execution-managed/using-docker/) 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](https://circleci.com/docs/guides/execution-managed/private-images/) 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](https://aws.amazon.com/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](https://circleci.com/docs/guides/permissions-authentication/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
`````````

* * *

#### GCP authentication

Using an image hosted on [GCP Artifact Registry](https://cloud.google.com/artifact-registry) requires authentication using GCP credentials, either via OIDC, or by setting environment variables. The two configuration options are described in the following sections:

#### Use OIDC

Authenticate using OpenID Connect (OIDC) using the `gcp_auth` field, as follows:

**Example:**

`````````
jobs:
  job_name:
    docker:
      - image: <region>-docker.pkg.dev/<project>/<repository>/<image>:<tag>
        gcp_auth:
          oidc_service_account: <service-account-email>
          workload_identity_pool: projects/<project-number>/locations/global/workloadIdentityPools/<pool-id>
          workload_identity_provider: <provider-id>
`````````

For steps to get set up with OIDC to pull images from GCP Artifact Registry, see the [Pull an Image From GCP Artifact Registry With OIDC](https://circleci.com/docs/guides/permissions-authentication/pull-an-image-from-gcp-gar-with-oidc/) page.

#### Use environment variables

By default, CircleCI uses the GCP credentials you provide by setting the `GCP_OIDC_SERVICE_ACCOUNT`, `GCP_WORKLOAD_IDENTITY_POOL`, and `GCP_WORKLOAD_IDENTITY_PROVIDER` project environment variables or context environment variables. When these are set and the image is hosted on GCP Artifact Registry, CircleCI automatically authenticates without requiring a `gcp_auth` field in your configuration:

**Example:**

`````````
jobs:
  build:
    docker:
      - image: us-docker.pkg.dev/my-project/my-repo/my-image:latest
`````````

* * *

### **`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

`image`

Y

String

The virtual machine image to use. View [available images](https://circleci.com/developer/images?imageType=machine). **Note:** This key is **not** supported for Linux VMs on installations of CircleCI Server. For information about customizing `machine` executor images on CircleCI installed on your servers, see our [Machine Provisioner Documentation](https://circleci.com/docs/server-admin/latest/operator/manage-virtual-machines-with-machine-provisioner/).

`docker_layer_caching`

N

Boolean

Set this to `true` to enable [Docker Layer Caching](https://circleci.com/docs/guides/optimize/docker-layer-caching/).

**Example:**

**Cloud:**

`````````
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
`````````

**Server:**

`````````
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:

*   [Ubuntu-2004](https://circleci.com/developer/machine/image/ubuntu-2004)
    
*   [Ubuntu-2204](https://circleci.com/developer/machine/image/ubuntu-2204)
    

More information on the software available in each image can be found in our [Discuss forum](https://discuss.circleci.com/tag/machine-images).

The machine executor supports [Docker Layer Caching](https://circleci.com/docs/guides/optimize/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](https://circleci.com/docs/guides/execution-managed/using-gpu/), the available images are:

*   `linux-cuda-11:default` v11.4, v11.6, v11.8 (default), Docker v20.10.24.
    
*   `linux-cuda-12:default` v12.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](https://circleci.com/developer/machine/image/android) 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](https://circleci.com/developer/orbs/orb/circleci/android).

For examples, refer to the [Using Android Images With the Machine Executor](https://circleci.com/docs/guides/execution-managed/android-machine-image/) 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:

*   [`windows-server-2022-gui` image](https://circleci.com/developer/machine/image/windows-server-2022-gui)
    
*   [`windows-server-2019` image](https://circleci.com/developer/machine/image/windows-server-2019)
    

More information on what software is available in each image can be found in our [Discuss forum](https://discuss.circleci.com/c/ecosystem/circleci-images/).

Alternatively, use the [Windows orb](https://circleci.com/developer/orbs/orb/circleci/windows) to manage your Windows execution environment. For examples, see the [Using the Windows Execution Environment](https://circleci.com/docs/guides/execution-managed/using-windows/) 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](https://circleci.com/docs/guides/execution-managed/using-gpu/), the available image is:

*   [`windows-server-2019-cuda`](https://circleci.com/developer/machine/image/windows-server-2019-cuda)
    

**Example:**

`````````
version: 2.1

jobs:
  build:
    machine:
      image: windows-server-2019-cuda:current
`````````

* * *

### **`macos`**

CircleCI supports running jobs on [macOS](https://developer.apple.com/macos/), to allow you to build, test, and deploy apps for macOS, [iOS](https://developer.apple.com/ios/), [tvOS](https://developer.apple.com/tvos/) and [watchOS](https://developer.apple.com/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

`xcode`

Y

String

The version of Xcode that is installed on the virtual machine, see the [Supported Xcode Versions Section of the Testing iOS](https://circleci.com/docs/guides/execution-managed/using-macos/#supported-xcode-versions) document for the complete list.

**Example:** Use a macOS virtual machine with Xcode version 26.4.0:

`````````
jobs:
  build:
    macos:
      xcode: 26.4.0
`````````

* * *

#### **`branches` - DEPRECATED**

This key is deprecated. Use [workflows filtering](#jobfilters) 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](https://support.circleci.com/hc/en-us/requests/new) 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](https://circleci.com/docs/guides/execution-runner/runner-overview/).

For example:

`````````
jobs:
  job_name:
    machine: true
    resource_class: <my-namespace>/<my-runner>
`````````

* * *

### Docker execution environment

Set a resource class for a Docker job

`````````
jobs:
  build:
    docker:
      - image: cimg/base:2024.12
    resource_class: xlarge
    steps:
      ... // other config
`````````

Set a resource class for a Docker job using an expression

`````````
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](https://circleci.com/product/features/resource-classes/). Resource class access is dependent on your [Plan](https://circleci.com/docs/guides/plans-pricing/plan-overview/).

    

Class

vCPUs

RAM

Cloud

Server

`small`

1

2GB

**Yes**

**Yes**

`medium`

2

4GB

**Yes**

**Yes**

`medium+`

3

6GB

**Yes**

**Yes**

`large`

4

8GB

**Yes**

**Yes**

`xlarge`

8

16GB

**Yes**

**Yes**

`2xlarge`

16

32GB

**Yes**

**Yes**

`2xlarge+`

20

40GB

**Yes**

**Yes**

#### Arm

**Arm on Docker** For credit and access information see the [Resource classes page](https://circleci.com/product/features/resource-classes/). Resource class access is dependent on your [Plan](https://circleci.com/docs/guides/plans-pricing/plan-overview/)

To find out which CircleCI Docker convenience images support Arm resource classes, you can refer to [Docker Hub](https://hub.docker.com/u/cimg):

1.  Select the image (for example, `cimg/python`).
    
2.  Select the **tags** tab.
    
3.  View what is supported under **OS/ARCH** for the latest tags. For example, `cimg/python` has `linux/amd64` and `linux/arm64`, which means Arm **is** supported.
    

    

Class

vCPUs

RAM

Cloud

Server

`arm.medium`

2

8 GB

**Yes**

**No**

`arm.large`

4

16 GB

**Yes**

**No**

`arm.xlarge`

8

32 GB

**Yes**

**No**

`arm.2xlarge`

16

64 GB

**Yes**

**No**

* * *

#### LinuxVM execution environment

     

Class

vCPUs

RAM

Disk Size

Cloud

Server

`medium`

2

7.5 GB

150GB

**Yes**

**Yes**

`large`

4

15 GB

150GB

**Yes**

**Yes**

`xlarge`

8

32 GB

150GB

**Yes**

**Yes**

`2xlarge`

16

64 GB

150GB

**Yes**

**Yes**

`2xlarge+`

32

64 GB

150GB

**Yes**

**Yes**

**Example:**

**Cloud:**

`````````
jobs:
  build:
    machine:
      image: ubuntu-2004:2024.01.2 # recommended linux image
    resource_class: large
    steps:
      ... // other config
`````````

**Server:**

`````````
jobs:
  build:
    machine: true
    resource_class: large
    steps:
      ... // other config
`````````

* * *

#### LinuxVM (gen2) execution environment

     

Class

vCPUs

RAM

Disk Size

Cloud

Server

`medium.gen2`

2

8 GiB

150GB

**Yes**

**No**

`large.gen2`

4

16 GiB

150GB

**Yes**

**No**

`xlarge.gen2`

8

32 GiB

150GB

**Yes**

**No**

`2xlarge.gen2`

16

64 GiB

150GB

**Yes**

**No**

`2xlarge+.gen2`

32

128 GiB

150GB

**Yes**

**No**

**Example:**

`````````
jobs:
  build:
    machine:
      image: ubuntu-2404:current # recommended linux image
    resource_class: large.gen2
    steps:
      ... // other config
`````````

* * *

#### macOS execution environment

    

Class

vCPUs

RAM

Cloud

Server

`m4pro.medium`

6 @ 4.51 GHz

28GB

**Yes**

**No**

`m4pro.large`

12 @ 4.51 GHz

56GB

**Yes**

**No**

**Example:**

`````````
jobs:
  build:
    macos:
      xcode: 26.4.0
    resource_class: m4pro.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](https://circleci.com/docs/guides/execution-runner/runner-overview/).

* * *

#### Windows execution environment

     

Class

vCPUs

RAM

Disk Size

Cloud

Server

`windows.medium` (default)

4

15GB

200 GB

**Yes**

**Yes**

`windows.large`

8

30GB

200 GB

**Yes**

**Yes**

`windows.xlarge`

16

60GB

200 GB

**Yes**

**Yes**

`windows.2xlarge`

32

128GB

200 GB

**Yes**

**Yes**

**Using server?** Check with your systems administrator whether you have access to the Windows execution environment.

**Example:**

**Cloud:**

`````````
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'
`````````

**Server:**

`````````
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

`gpu.nvidia.small`

4

16

1

NVIDIA Tesla P4

16

150

**Yes**

**No**

`gpu.nvidia.small.gen2`

4

16

1

NVIDIA A10G

24

150

**Yes**

**No**

`gpu.nvidia.small.multi`

4

15

2

NVIDIA Tesla T4

16

150

**Yes**

**No**

`gpu.nvidia.medium.multi`

8

30

4

NVIDIA Tesla T4

16

150

**Yes**

**No**

`gpu.nvidia.medium`

8

30

1

NVIDIA Tesla T4

16

150

**Yes**

**No**

`gpu.nvidia.large`

8

30

1

NVIDIA Tesla V100

16

150

**Yes**

**No**

**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](#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

`windows.gpu.nvidia.medium`

16

60

1

NVIDIA Tesla T4

16

200

**Yes**

**No**

**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](https://support.circleci.com/hc/en-us/requests/new) if you would like to request access._

* * *

#### Arm VM execution-environment

     

Class

vCPUs

RAM

Disk Size

Cloud

Server

`arm.medium` (default)

2

8GB

100 GB

**Yes**

**Yes**

`arm.large`

4

16GB

100 GB

**Yes**

**Yes**

`arm.xlarge`

8

32GB

100 GB

**Yes**

**Yes**

`arm.2xlarge`

16

64GB

100 GB

**Yes**

**Yes**

**Using server?** Check with your systems administrator whether you have access to the Arm execution environment.

**Example:**

**Cloud:**

`````````
jobs:
  my-job:
    machine:
      image: ubuntu-2004:2024.01.2
    resource_class: arm.medium
    steps:
      - run: uname -a
      - run: echo "Hello, Arm!"
`````````

**Server:**

`````````
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`](#jobs).

In general all steps can be described as:

   

Key

Required

Type

Description

`<step_type>`

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](https://circleci.com/docs/guides/orchestrate/migrate-from-deploy-to-run/).

   

Key

Required

Type

Description

`command`

Y

String

Command to run via the shell

`name`

N

String

Title of the step to be shown in the CircleCI UI (default: full `command`)

`shell`

N

String

Shell to use for execution command (default: See [Default Shell Options](#default-shell-options))

`environment`

N

Map

Additional environment variables, locally scoped to command

`background`

N

Boolean

Whether or not this step should run in the background (default: false)

`working_directory`

N

String

The directory where this step runs. CircleCI interprets this relative to the [`working_directory`](#jobs) of the job. (default: `.`)

`no_output_timeout`

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](#jobs).

`when`

N

String

[Specify when to enable or disable the step](#the-when-attribute). Takes the following values: `always`, `on_success`, `on_fail` (default: `on_success`)

`max_auto_reruns`

N

Integer

The maximum number of times to automatically rerun the step if it fails. Must be between `1` and `5`.

`auto_rerun_delay`

N

String

The delay between reruns of the step if it fails. This delay can only be set along with `max_auto_reruns`. The string is a decimal with unit suffix using either seconds `s` or minutes `m` up to a maximum of 10 minutes, such as "10s", "2m".

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](#background-commands) 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](https://linux.die.net/man/1/bash).

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](https://circleci.com/docs/guides/orchestrate/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_success` is the default value.

`always`

The step runs regardless of the exit status of previous steps. Use `always` when 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_fail` include 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

`max_auto_reruns`

N

Integer

The maximum number of times to automatically rerun the step if it fails. Must be between `1` and `5`.

`auto_rerun_delay`

N

String

The delay between reruns of the step if it fails. This delay can only be set along with `max_auto_reruns`. The string is a decimal with unit suffix using either seconds `s` or minutes `m` up to a maximum of 10 minutes, such as "10s", "2m". If you do not supply a delay, the rerun starts directly after the step fails.

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:**

CircleCI job configured to automatically rerun a step up to 3 times if it fails with a 10 second delay between attempts

`````````
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](https://circleci.com/docs/guides/orchestrate/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](https://circleci.com/docs/reference/reusing-config/#defining-conditional-steps) for more details.

   

Key

Required

Type

Description

`condition`

Y

Logic

[A Logic Statement](#logic-statements)

`steps`

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

`method`

N

String

Checkout method. Valid options include `blobless` and `full`. (default: `blobless`)

`path`

N

String

The directory where CircleCI checks out code. CircleCI interprets this relative to the [`working_directory`](#jobs) of the job. (default: `.`)

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](https://circleci.com/docs/guides/permissions-authentication/users-organizations-and-integrations-guide/#establish-the-authenticity-of-an-ssh-host). 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](https://lore.kernel.org/git/kl6lh6qyrnjm.fsf@chooglen-macbookpro.roam.corp.google.com/) 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`**](#restorecache) and would like to use garbage collection to reduce its size, you may wish to use a [**`run`**](#run) step with command `git gc` before doing so.

* * *

### **`setup_remote_docker`**

*   `setup_remote_docker` is not compatible with the `machine` executor. See [Docker Layer Caching in Machine Executor](https://circleci.com/docs/guides/optimize/docker-layer-caching/#machine-executor) for information on how to enable DLC with the `machine` executor.
    
*   The `version` key is not currently supported on CircleCI Server. Contact your system administrator for information about the Docker version installed in your remote Docker environment. If you are on server 4.x, find the [Default AWS AMI Lists](https://circleci.com/docs/server-admin/latest/operator/manage-virtual-machines-with-machine-provisioner/#default-aws-ami-lists).
    

Allows Docker commands to be run locally. See [Running Docker Commands](https://circleci.com/docs/guides/execution-managed/building-docker-images/) for details.

   

Key

Required

Type

Description

`docker_layer_caching`

N

boolean

Set this to `true` to enable [Docker Layer Caching](https://circleci.com/docs/guides/optimize/docker-layer-caching/) in the Remote Docker Environment (default: `false`)

`version`

N

String

Version string of Docker you would like to use (default: `24.0.9`). View the list of [Supported Docker Versions](https://circleci.com/docs/guides/execution-managed/building-docker-images/#docker-version).

**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](#restorecache). Learn more on the [Caching Dependencies](https://circleci.com/docs/guides/optimize/caching/) page.

Cache retention can be customized on the [CircleCI web app](https://app.circleci.com/) by navigating to **Plan**  **Usage Controls**.

   

Key

Required

Type

Description

`paths`

Y

List

List of directories which should be added to the cache

`key`

Y

String

Unique identifier for this cache

`name`

N

String

Title of the step to be shown in the CircleCI UI (default: "Saving Cache")

`when`

N

String

[Specify when to enable or disable the step](#the-when-attribute). Takes the following values: `always`, `on_success`, `on_fail` (default: `on_success`)

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

`{{ .Branch }}`

The VCS branch currently being built.

`{{ .BuildNum }}`

The CircleCI build number for this build.

`{{ .Revision }}`

The VCS revision currently being built.

`{{ .CheckoutKey }}`

The SSH key used to checkout the repository.

`{{ .Environment.variableName }}`

The environment variable `variableName` (supports any environment variable [Exported by CircleCI](https://circleci.com/docs/guides/security/env-vars/) or added to a specific [context](https://circleci.com/docs/guides/security/contexts/)\--not any arbitrary environment variable).

`{{ checksum "filename" }}`

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 `package-lock.json`, `pom.xml` or `project.clj`. This file must not change between `restore_cache` and `save_cache`, otherwise CircleCI saves the cache under a different cache key than the one it used at `restore_cache` time.

`{{ epoch }}`

The current time in seconds since the UNIX epoch.

`{{ arch }}`

The OS and CPU information. Useful when caching compiled binaries that depend on OS and CPU architecture, for example, `darwin amd64` versus `linux i386/32-bit`.

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](https://circleci.com/docs/reference/faq/#calculate-monthly-storage-and-network-costs) page.
    
*   It takes time to upload the cache.
    
*   Best practice is to have a `key` that 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 `save_cache` paths. Visit the [Ideas board](https://ideas.circleci.com/cloud-feature-requests/p/support-wildcards-in-savecachepaths) and vote for this feature if it would be useful for you or your organization.

* * *

### **`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](#savecache). Learn more in [The Caching Documentation](https://circleci.com/docs/guides/optimize/caching/).

   

Key

Required

Type

Description

`key`

Y (1)

String

Single cache key to restore

`keys`

Y (1)

List

List of cache keys to check. CircleCI restores the cache from the first existing key.

`name`

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](#savecache).

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`**](#run) for current processes. If you have parallelism `> 1` in your job, see the [Migrate From Deploy to Run](https://circleci.com/docs/guides/orchestrate/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](https://circleci.com/docs/guides/optimize/artifacts/) page for more information.

   

Key

Required

Type

Description

`path`

Y

String

Directory in the primary container to save as job artifacts

`destination`

N

String

Prefix added to the artifact paths in the artifacts API (default: the directory of the file specified in `path`)

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](https://app.circleci.com/) by navigating to **Plan**  **Usage Controls**.

**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](https://circleci.com/docs/guides/test/collect-test-data/) page.

You can also store test results as build artifacts. For steps, refer to [the `store_artifacts` step](#storeartifacts) section.

   

Key

Required

Type

Description

`path`

Y

String

Path (absolute, or relative to your `working_directory`) to directory containing `JUnit` XML test metadata files, or to a single test file.

**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](https://circleci.com/docs/guides/orchestrate/workspaces/) 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](https://app.circleci.com/) by navigating to **Plan**  **Usage Controls**.

   

Key

Required

Type

Description

`root`

Y

String

Either an absolute path or a path relative to `working_directory`

`paths`

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](https://golang.org/pkg/path/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](https://circleci.com/docs/guides/orchestrate/workspaces/) page.

   

Key

Required

Type

Description

`at`

Y

String

Directory to attach the workspace to.

Workspace storage retention can be customized on the [CircleCI web app](https://app.circleci.com/) by navigating to **Plan**  **Usage Controls**.

**Example:**

`````````
- attach_workspace:
    at: /tmp/workspace
`````````

The lifetime of artifacts, workspaces, and caches can be customized on the [CircleCI web app](https://app.circleci.com/) by navigating to **Plan**  **Usage Controls**. 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](https://circleci.com/docs/guides/integration/add-ssh-key/) page.

**Using server?** CircleCI Server supports only MD5 fingerprints. You can see the MD5 fingerprint in CircleCI under **Project Settings**  **SSH keys**  **Additional SSH keys**. An upcoming server release is planned to include SHA256 support.

   

Key

Required

Type

Description

`fingerprints`

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](https://circleci.com/docs/guides/orchestrate/pipeline-variables/) 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](https://circleci.com/pricing/) is required to access IP ranges.

Enables jobs to go through a set of well-defined IP address ranges. See [IP Ranges](https://circleci.com/docs/guides/security/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](https://circleci.com/docs/guides/orchestrate/workflows/) 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

`version`

Y if config version is `2`

String

Should currently be `2`

`````````
workflows:
  version: 2
  my-workflow:
    jobs:
      - my-job
`````````

* * *

### **<`workflow_name`\>**

A unique name for your workflow.

`````````
workflows:
  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](https://circleci.com/docs/guides/orchestrate/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

`triggers`

N

Array

Should currently be `schedule`.

`````````
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](https://circleci.com/docs/guides/orchestrate/migrate-scheduled-workflows-to-schedule-triggers/) 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](https://circleci.com/docs/guides/orchestrate/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

`cron`

Y

String

See the [`crontab` man page](https://pubs.opengroup.org/onlinepubs/7908799/xcu/crontab.html).

`````````
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

`filters`

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](https://circleci.com/docs/guides/orchestrate/workflows/#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 `only` nor `ignore`, the job runs on all branches. If you specify both `only` and `ignore`, CircleCI uses `only` and ignores `ignore`.
    

`````````
workflows:
  commit:
    jobs:
      - test
      - deploy
  nightly:
    triggers:
      - schedule:
          cron: "0 0 * * *"
          filters:
            branches:
              only:
                - main
                - /^release\/.*/
    jobs:
      - coverage
`````````

   

Key

Required

Type

Description

`branches`

Y

Map

A map defining rules for execution on specific branches

`only` 1

N

String, or List of Strings

Either a single branch specifier, or a list of branch specifiers

`ignore` 1

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](#logic-statements) 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](https://circleci.com/docs/guides/orchestrate/workflows/) for more examples and conceptual information.

* * *

## **`jobs`**

A job can have the keys `requires`, `name`, `context`, `type`, and `filters`.

   

Key

Required

Type

Description

`jobs`

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](https://circleci.com/docs/guides/orchestrate/how-to-override-config/) page.

   

Key

Required

Type

Description

`override-with`

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-group` key.
    
*   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](#jobs).
    

**Pipeline order protection in serial groups**

Jobs in a serial group follow an order protection mechanism, as follows:

*   Jobs start in the order they join the queue, but are _accepted_ based on pipeline number.
    
*   If a group is waiting/running and another job in the same project attempts to join the queue with a lower pipeline number, the job is skipped.
    
*   This immediate skip process maintains order integrity, preventing unintended work in a build, such as a deployment job running a previous version.
    

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

`serial-group`

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](https://circleci.com/docs/guides/orchestrate/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

`requires`

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 `requires` items:

*   Job name (a required job that must succeed for the job to start).
    
*   Map of job name to status (a required job that must attain the specified status for the job to start).
    
*   Map of job name to a list of statuses (a required job that must attain one of the specified status for the job to start).
    

The possible **status** values are: `success`, `failed`, `canceled`, `unauthorized`, `not_run`, and `terminal`.

`````````
workflows:
  my-workflow:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - build
            - test
      - notify-build-canceled:
          requires:
            - build: canceled
      - cleanup:
          requires:
            - deploy:
              - success
              - failed
              - canceled
              - unauthorized
              - not_run
      - cleanup-shorthand:
          requires:
            - deploy: terminal  # equivalent to [success, failed, canceled, unauthorized, not_run]
`````````

* * *

#### **`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

`name`

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](https://circleci.com/docs/guides/security/contexts/) document for adding a context in the application settings.

   

Key

Required

Type

Description

`context`

N

String/List

The name of the context(s). The initial default name is `org-global`. Each context name must be unique. If using CircleCI Server, only a single context per workflow is supported. **Note:** A maximum of 100 unique contexts across all workflows is allowed.

Use a context for a job

`````````
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:

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](https://circleci.com/docs/guides/orchestrate/workflows/#holding-a-workflow-for-a-manual-approval) 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

`filters`

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](https://circleci.com/docs/guides/orchestrate/workflows/#using-regular-expressions-to-filter-tags-and-branches) page.

* * *

#### Expression-based job filters

Expression-based job filters allow you to conditionally run jobs based on the following:

*   [Pipeline Values](https://circleci.com/docs/reference/variables/#pipeline-values)
    
*   [Pipeline Parameters](https://circleci.com/docs/guides/orchestrate/pipeline-variables/#pipeline-parameters-in-configuration)
    

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](https://circleci.com/docs/guides/toolkit/vs-code-extension-overview/#test-run-your-config-from-vs-code):

`````````
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](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

`and`, `or`

These are short-circuiting boolean operators.

Equality

`==`, `!=`

String, numeric, and boolean equality. If the operands are of different types then `==` will evaluate `false`, and `!=` will evaluate `true`.

Equality

`starts-with`

String prefix equality, `"hello world" starts-with "hello"` evaluates as `true`. It is an error to use a non-string type as an operand.

Numeric comparison

`>=`, `>`, `⇐`, `<`

Numeric comparisons. It is an error to use a non-numeric type as an operand.

Negation

`not`

Boolean negation.

Note that `not` has very high precedence and so binds very tightly. Use sub-expressions to apply `not` to more complex expressions. For example, with `foo` being `true` and `bar` being `false`:

*   `not foo and bar` evaluates to `false`
    
*   `not (foo and bar)` evaluates to `true`
    

* * *

#### **`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 `only` will run the job.
    
*   Any branches that match `ignore` will not run the job.
    
*   If you specify neither `only` nor `ignore`, the job runs on all branches.
    
*   If you specify both `only` and `ignore`, CircleCI checks `only` before `ignore`.
    

   

Key

Required

Type

Description

`branches`

N

Map

A map defining rules for execution on specific branches.

`only`

N

String, or list of strings

Either a single branch specifier, or a list of branch specifiers.

`ignore`

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 `only` runs the job.
    
*   Any tags that match `ignore` does not run the job.
    
*   If neither `only` nor `ignore` are specified then the job is skipped for all tags.
    
*   If both `only` and `ignore` are specified the `only` is considered before `ignore`.
    

   

Key

Required

Type

Description

`tags`

N

Map

A map defining rules for execution on specific tags

`only`

N

String, or List of Strings

Either a single tag specifier, or a list of tag specifiers

`ignore`

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](https://circleci.com/docs/guides/orchestrate/workflows/#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](https://circleci.com/docs/guides/orchestrate/using-matrix-jobs/). In order to use the `matrix` stanza, you must use parameterized jobs.

   

Key

Required

Type

Description

`parameters`

Y

Map

A map of parameter names to every value the job should be called with

`exclude`

N

List

A list of argument maps that should be excluded from the matrix

`alias`

N

String

An alias for the matrix, usable from another job’s `requires` stanza. Defaults to the name of the job being executed

**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

`true`/`42`/`"a string"`

[Pipeline Value](https://circleci.com/docs/guides/orchestrate/pipeline-variables/#pipeline-values)

None

resolves to a truthy value

`<< pipeline.git.branch >>`

[Pipeline Parameter](https://circleci.com/docs/guides/orchestrate/pipeline-variables/#pipeline-parameters-in-configuration)

None

resolves to a truthy value

`<< pipeline.parameters.my-parameter >>`

`and`

N logic statements

all arguments are truthy

`and: [ true, true, false ]`

`or`

N logic statements

any argument is truthy

`or: [ false, true, false ]`

`not`

1 logic statement

the argument is not truthy

`not: true`

`equal`

N values

all arguments evaluate to equal values

`equal: [ 42, << pipeline.number >>]`

`matches`

`pattern` and `value`

`value` matches the `pattern`

`matches: { pattern: "^feature-.$", value: << pipeline.git.branch >> }+`

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](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) 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:

Use expression to determine parallelism for a job

`````````
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:

Direct expression in a job filter

`````````
workflows:
  my-workflow:
    jobs:
      - build:
          filters: pipeline.git.branch == "main" or pipeline.git.branch starts-with "release/"
`````````

Workflow `when` expression

`````````
workflows:
  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, the `and` expression evaluates to its second operand `10`.
    
*   If the condition is false, the `and` expression evaluates to false, and the `or` expression returns the fallback value `1`.
    

### 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

`and`, `or`

These are short-circuiting boolean operators.

Equality

`==`, `!=`

String, numeric, and boolean equality. If the operands are of different types then `==` will evaluate `false`, and `!=` will evaluate `true`.

Equality

`starts-with`

String prefix equality, `"hello world" starts-with "hello"` evaluates as `true`. It is an error to use a non-string type as an operand.

Numeric comparison

`>=`, `>`, `⇐`, `<`

Numeric comparisons. It is an error to use a non-numeric type as an operand.

Negation

`not`

Boolean negation.

Note that `not` has very high precedence and so binds very tightly. Use sub-expressions to apply `not` to more complex expressions. For example, with `foo` being `true` and `bar` being `false`:

*   `not foo and bar` evaluates to `false`
    
*   `not (foo and bar)` evaluates to `true`
    

### 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](https://circleci.com/docs/guides/orchestrate/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](https://circleci.com/docs/guides/execution-managed/private-images/).

`````````
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
`````````