Conditional Execution of Steps

Skip specific pipeline steps according to one or more conditions

For each step in a codefresh.yml file, you can define a set of conditions which need to be satisfied in order to execute the step. (An introduction to the codefresh.yml file can be found here.)

There are currently two main methods to define conditions: branch conditions and expression conditions.

Branch Conditions

Usually, you’ll want to define a branch condition, be it of the type ignore for blacklisting a set of branches or of the type only for whitelisting a set of branches. Each branch specification can either be an exact branch name, e.g. master, or a regular expression, e.g. /hotfix$/. Case insensitive regexps (/^FB-/i) are also supported.

Here are some examples:

Only execute for the master branch:

only-master-branch.yml

build-step:
  description: Building the image.
  type: build
  dockerfile: Dockerfile
  image-name: someRepo/someUser
  when:
    branch:
      only:
        - master

Only execute for branches whose name begins with FB- prefix (feature branches):

only-feature-branches.yml

build-step:
  description: Building the image.
  type: build
  dockerfile: Dockerfile
  image-name: someRepo/someUser
  when:
    branch:
      only:
        - /^FB-.*/i

Ignore the develop branch and master branch:

ignore-master-and-develop-branch.yml

build-step:
  description: Building the image.
  type: build
  dockerfile: Dockerfile
  image-name: someRepo/someUser
  when:
    branch:
      ignore:
        - master
        - develop

We use JavaScript regular expressions for the syntax in branch conditions.

Condition expressions

Alternatively, you can use more advanced condition expressions.

This follows the standard condition expression syntax. In this case, you can choose to execute if all expression conditions evaluate to true, or to execute if any expression conditions evaluate to true.

Here are some examples. Execute if the string [skip ci] is not part of the main repository commit message AND if the branch is master

all-conditions.yml

build-step:
  description: Building the image.
  type: build
  dockerfile: Dockerfile
  image-name: someRepo/someUser
  when:
    condition:
      all:
        noSkipCiInCommitMessage: 'includes(lower("${{CF_COMMIT_MESSAGE}}"), "skip ci") == false'
        masterBranch: '"${{CF_BRANCH}}" == "master"'

Execute if the string [skip ci] is not part of the main repository commit message, OR if the branch is not a feature branch (i.e. name starts with FB-)

any-condition.yml

build-step:
  description: Building the image.
  type: build
  dockerfile: Dockerfile
  image-name: someRepo/someUser
  when:
    condition:
      any:
        noSkipCiInCommitMessage: 'includes(lower("${{CF_COMMIT_MESSAGE}}"), "skip ci") == false'
        notFeatureBranch: 'match("${{CF_BRANCH}}", "^FB-", true) == false'

Execute steps according to the presence of a variable

If a variable does not exist in a Codefresh pipeline, then it will simply stay as a string inside the definition. When the ${{MY_VAR}} variable is not available, the engine will literally print ${{MY_VAR}}, because that variable doesn’t exist.

You can use this mechanism to decide which steps will be executed if a variable exists or not.

codefresh.yml

version: "1.0"
steps:
  step1:
    title: "Running if variable exists"
    type: "freestyle" 
    image: "alpine:3.9" 
    commands:
      - echo "Step 1 is running"
    when:
      condition:
        all:
          whenVarExists: 'includes("${{MY_VAR}}", "{{MY_VAR}}") == false'
  step2:
    title: "Running if variable does not exist"
    type: "freestyle" 
    image: "alpine:3.9" 
    commands:
      - echo "Step 2 is running"
    when:
      condition:
        all:
          whenVarIsMissing: 'includes("${{MY_VAR}}", "{{MY_VAR}}") == true'

Try running the pipeline above and see how it behaves when a variable called MY_VAR exists (or doesn’t exist).

Notice that if you use this pattern a lot it means that you are trying to create a complex pipeline that is very smart. We suggest you create instead multiple simple pipelines for the same project.