Skip to content
Latchkey

How to Define Reusable Commands in CircleCI

A top-level commands: block bundles a sequence of steps behind a name you can invoke from any job, with parameters for the bits that change.

Declare a command under commands: with optional parameters:, then call it as a step by name. Pass values with the same with:-style mapping you use for orb commands.

Steps

  • Add a commands: block at the top level (requires version: 2.1).
  • Give the command a steps: list and declare parameters: for the variable parts.
  • Invoke it inside a job as a step, passing any parameters as keys.

Config

.circleci/config.yml
version: 2.1
commands:
  install_deps:
    parameters:
      cache_key:
        type: string
        default: deps
    steps:
      - restore_cache:
          keys:
            - << parameters.cache_key >>-{{ checksum "package-lock.json" }}
      - run: npm ci
      - save_cache:
          key: << parameters.cache_key >>-{{ checksum "package-lock.json" }}
          paths: [~/.npm]
jobs:
  test:
    docker:
      - image: cimg/node:20.11
    steps:
      - checkout
      - install_deps
      - run: npm test

Gotchas

  • Commands need version: 2.1; on 2.0 config the commands: key fails schema validation.
  • Reference parameters with << parameters.name >>, not the ${{ }} syntax used by other CI systems.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →