jobs.<job_id>.steps[*].if

3 minute read

Use jobs.<job_id>.steps[*].if to require a condition be met before a step is run. You can use any supported context and expression to create a conditional.

When you use expressions in an if conditional, you may omit the ${{ }} expression syntax because CloudBees platform automatically evaluates the if conditional as an expression. However, this rule does not apply everywhere.

You must use the ${{ }} expression syntax or escape with '', "", or () when the expression starts with !, since ! is reserved notation in YAML format.

Using the ${{ }} expression syntax turns the contents into a string, and strings are truthy. For example, if: true && ${{ false }} will evaluate to true.

Example usage: Contexts

A conditional at the job level cannot reference any step outputs. However, a conditional within a step can reference previous steps in the same job.

In the following example, the step only runs when the event type is a push and the branch is main.

steps: - name: My first step uses: docker://alpine:3.18 if: ${{ cloudbees.event_name == 'push' && cloudbees.scm.ref == 'refs/heads/main' }} run: echo This event is a push on the main branch.

In the following example, the first step is referenced in the second step.

jobs: my-job: steps: - name: First step id: detect_build_type uses: docker://alpine:3.19 run: | if [ '${{ cloudbees.scm.ref }}' = refs/heads/main ]; then echo true > $CLOUDBEES_OUTPUTS/is_release_build fi - name: Second step if: ${{ steps.detect_build_type.outputs.is_release_build }} uses: docker://alpine:3.19 run: | echo Publish a release...

Example usage: Status checks

Use an expression to check the status of a job step. The following expressions are supported:

success()

The default for any step is success(), which returns true if all previous job steps are successful.

failure()

failure() returns true if any previous job step fails. If a job is dependent on another job, a failure in the ancestor job also means failure() returns true.

In the following example, My backup step only runs when the previous step (My first step) of the job fails.

steps: - name: My first step uses: cloudbees/checkout@v1 - name: My backup step if: ${{ failure() }} uses: cloudbees/kaniko@v1
Because success() is automatically applied to all non-status check conditions, you must override this in any extra conditions you add to a step to run after a failure.

always()

Use always() to always execute a step, regardless of the status of any previous step.

CloudBees recommends that you only use always for steps that are not critical to the workflow run, for example, sending a log file or test results.

In the following example, Test results always runs.

steps: - name: Test results uses: cloudbees-io/publish-test-results@v1 if: ${{always()}} with: test-type: playwright folder-name: ${{ cloudbees.workspace }}/results.json

Example usage: Using secrets

You cannot directly reference a secret in jobs.<job_id>.steps[*].if. CloudBees recommends setting secrets as environment variables at the job level, then referencing these environment variables in the conditional, as in the following example:

name: Check secret set status on: push jobs: my-job: env: my_secret: ${{ secrets.my_secret }} steps: - uses: docker://alpine:3.18 if: ${{ env.my_secret != '' }} run: echo 'Step runs only if secret value is set.' - uses: docker://alpine:3.18 if: ${{ env.my_secret == '' }} run: echo 'Step runs only if secret value is not set.'

If a secret is not set, the return value of an expression referencing the secret (such as ${{ secrets.my_secret }} is an empty string.