> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/continuous-delivery/use-continuous-delivery/cd-building-blocks/executions/step-and-stage-conditional-execution-settings.md).

# Stage and step conditional execution settings

Configure when pipeline stages and steps run using Conditional Execution settings and JEXL conditions

This topic describes pipeline stage and step **Conditional Execution** settings. Use these settings to run a stage or step only when prior stages or steps succeed or fail, always, or when a JEXL condition evaluates to true.

Open **Conditional Execution** on the stage or step **Advanced** settings panel.

***

## What you will learn from this topic

* How [failure strategy](#important-notes) interacts with Conditional Execution
* How [stage Conditional Execution](#stage-conditional-execution-settings) options work
* How [step Conditional Execution](#step-conditional-execution-settings) options work
* How to use [variable expressions and deployment status](#variable-expressions-in-conditional-execution-settings) in JEXL conditions
* Why some expressions are [resolved or unresolved](#resolved-and-unresolved-expressions-during-conditional-execution) during Conditional Execution

***

## Before you begin

This topic assumes the following knowledge:

* **Harness expressions**: Familiarity with pipeline and stage expressions. Go to [Harness variables](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables) to review built-in variables.
* **Failure strategies**: Familiarity with how stages and steps handle errors. Go to [Step and stage failure strategy references](/continuous-delivery/use-continuous-delivery/cd-building-blocks/executions/step-failure-strategy-settings.md) to review failure strategy options.
* **JEXL basics**: Conditional Execution custom conditions use [JEXL expressions](http://commons.apache.org/proper/commons-jexl/reference/examples.html).

***

## Important notes

Review these rules before you combine Conditional Execution with failure strategies.

### Failure strategy takes precedence over Conditional Execution

Harness pipeline stages and steps both include **Conditional Execution** and **Failure Strategy** settings:

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-79ae30c9af74d564dd0b84e6b6211bfe6204049c%2Fstep-skip-condition-settings-09.png?alt=media)

Using these settings together in multiple stages requires some consideration.

For example, you have a pipeline with two stages: **stage 1** followed by **stage 2**.

Stage 2's **Conditional Execution** is set to **Execute this step only if the prior stage or step failed**. Stage 1's **Failure Strategy** is set to **Rollback Stage on All Errors**.

If stage 1 has any error, it is rolled back and is not considered a failure. Stage 2's **Conditional Execution** does not run.

To get stage 2 to execute, set the stage 1 **Failure Strategy** to **Ignore Failure**. Rollback does not occur, and stage 2's **Conditional Execution** runs.

To ensure a step executes even if the rollback fails, include it in the Rollback stage, configure **Conditional Execution** to **Always execute this stage** for your step, and then set the previous step's **Failure Strategy** to **Mark as failure** for all errors. Because you would not usually want the rollback to continue when there are errors, you must make these two changes to ensure the execution.

### Stage and step priority

The stage Conditional Execution applies to all steps that do not have their own Conditional Execution. A step's Conditional Execution overrides its stage's Conditional Execution.

### Conditional Execution settings do not apply to child entities

A stage or step group failure strategy automatically applies to its child entities (steps). Conditional Execution settings do not work this way.

Conditional Execution settings are specific to the step, stage, or step group where they are applied. Conditional Execution settings do not transmit to the child entities of that step, stage, or step group.

***

## Stage Conditional Execution settings

Configure the following options on a stage.

### If the pipeline executes successfully up to this point

Select this option if you only want this stage to run when all previous stages were successful.

This is the default setting and used most of the time.

### If the previous pipeline or stage fails

Select this option if you always want this stage to run only if the prior pipeline or stage failed.

### Always

Select this option if you always want this stage to run regardless of the success or failure of previous stages.

### And execute this stage only if the following JEXL condition evaluates to true

Only execute this stage if a [JEXL expression](http://commons.apache.org/proper/commons-jexl/reference/examples.html) is met (evaluates to **true**).

In the JEXL expression, you can use any of the pipeline variables, including the output of any previous steps.

Examples:

* `<+pipeline.stages.cond.spec.execution.steps.echo.status> == "SUCCEEDED"`
* `<+environment.name> != "QA"`

Go to [Built-in custom Harness variables reference](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables) to use variable expressions.

***

## Step Conditional Execution settings

Configure the following options on a step.

### If the stage executes successfully up to this point

Select this option if you only want this step to run when all previous steps were successful.

This is the default setting and used most of the time.

### If the previous step fails

Select this option if you always want this step to run only if the prior step failed.

### Always

Select this option if you always want this step to run regardless of the success or failure of previous steps.

### And execute this step only if the following JEXL condition evaluates to true

Only execute this step if a [JEXL expression](http://commons.apache.org/proper/commons-jexl/reference/examples.html) is met (evaluates to **true**).

In the JEXL expression, you can use any of the pipeline variables, including the output of any previous steps.

Examples:

* `<+pipeline.stages.cond.spec.execution.steps.echo.status> == "SUCCEEDED"`
* `<+environment.name> != "QA"`

Go to [Use Harness expressions](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables) to use variable expressions.

***

## Variable expressions in Conditional Execution settings

Stages and steps support variable expressions in the JEXL conditions of their **Conditional Execution** settings.

You can only use variable expressions in the JEXL conditions that can be resolved before the stage.

Since **Conditional Execution** settings are used to determine if the stage should be run, you cannot use variable expressions that cannot be resolved until the stage is run.

***

## Deployment status

Deployment status values are a Java enum. The list of values can be seen in the deployments **Status** filter:

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-392940cc709f18f55c4b70fd746887582021e99f%2Fstep-skip-condition-settings-10.png?alt=media)

You can use any status value in a JEXL condition. For example, `<+pipeline.stages.cond.spec.execution.steps.echo.status> == "FAILED"`.

***

## Resolved and unresolved expressions during Conditional Execution

This section explains why some expressions in Conditional Execution are unresolved during execution.

Consider the following pipeline YAML:

<details>

<summary>Stage condition example YAML</summary>

```yaml
  tags: {}
  stages:
    - stage:
        name: deploy_stage
        identifier: deploy_stage
        description: ""
        type: Deployment
        spec:
          deploymentType: Kubernetes
          service:
            serviceRef: harnessguestbook
            serviceInputs:
              serviceDefinition:
                type: Kubernetes
                spec:
                  artifacts:
                    primary:
                      sources:
                        - identifier: deployed_artifact_version
                          type: DockerRegistry
                          spec:
                            tag: <+input>
          environment:
            environmentRef: <+input>
            deployToAll: false
            environmentInputs: <+input>
            serviceOverrideInputs: <+input>
            infrastructureDefinitions: <+input>
          execution:
            steps:
              - step:
                  name: Rollout Deployment
                  identifier: rolloutDeployment
                  type: K8sRollingDeploy
                  timeout: 10m
                  spec:
                    skipDryRun: false
                    pruningEnabled: false
            rollbackSteps:
              - step:
                  name: Rollback Rollout Deployment
                  identifier: rollbackRolloutDeployment
                  type: K8sRollingRollback
                  timeout: 10m
                  spec:
                    pruningEnabled: false
        tags: {}
        failureStrategies:
          - onFailure:
              errors:
                - AllErrors
              action:
                type: StageRollback
        when:
          pipelineStatus: Success
          condition: <+env.name> == "harnessdevenv"
```

</details>

The stage in the example runs only if the environment name is `harnessdevenv`.

When you select **Run**, you are prompted to provide a value for your environment at runtime. In this case, suppose you select the value as `harnessdevenv`:

![Unresolved pipeline input](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-f8c8d617667eb814af2c2f420b0aae5a08ac83f6%2Funresolved_runtime_input.png?alt=media)

When you run the pipeline, the stage `deploy_stage` is skipped because Conditional Execution resolves to `null`.

![Unresolved execution](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-b9c565ecfb62e3469a9a634b1e9fffc8b8a6d280%2Funresolved_execution_1.png?alt=media)

When you run a deploy stage, pipeline execution follows this flow:

1. Harness checks the stage Conditional Execution, then starts filling the variables defined in the stage definition.
2. Harness checks the **Service** step, then fetches the environment and infrastructure information.

![Unresolved expression execution](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-69918c4a10121b0b4cf7849a2c8b74315aba03b6%2Funresolved_expression_execution_2.png?alt=media)

3. When the stage starts, Harness checks the step Conditional Execution and proceeds to resolve the variable step.

In this case, when the pipeline ran, Harness first checked the stage `deploy_stage` Conditional Execution. Harness checked for the environment name, `harnessdevenv`, but it resolved to null because the stage had not yet fetched environment information.

### Resolved variable example

The following example shows a case where the condition resolves successfully because it is evaluated on a step after environment information is available.

<details>

<summary>Step condition example YAML</summary>

```yaml
  tags: {}
  stages:
    - stage:
        name: deploy_stage
        identifier: deploy_stage
        description: ""
        type: Deployment
        spec:
          deploymentType: Kubernetes
          service:
            serviceRef: harnessguestbook
            serviceInputs:
              serviceDefinition:
                type: Kubernetes
                spec:
                  artifacts:
                    primary:
                      sources:
                        - identifier: deployed_artifact_version
                          type: DockerRegistry
                          spec:
                            tag: <+input>
          environment:
            environmentRef: <+input>
            deployToAll: false
            environmentInputs: <+input>
            serviceOverrideInputs: <+input>
            infrastructureDefinitions: <+input>
          execution:
            steps:
              - step:
                  type: ShellScript
                  name: ShellScript_1
                  identifier: ShellScript_1
                  spec:
                    shell: Bash
                    executionTarget: {}
                    source:
                      type: Inline
                      spec:
                        script: echo hello
                    environmentVariables: []
                    outputVariables: []
                  timeout: 10m
                  when:
                    stageStatus: Success
                    condition: <+env.name> == "harnessdevenv"
              - step:
                  name: Rollout Deployment
                  identifier: rolloutDeployment
                  type: K8sRollingDeploy
                  timeout: 10m
                  spec:
                    skipDryRun: false
                    pruningEnabled: false
            rollbackSteps:
              - step:
                  name: Rollback Rollout Deployment
                  identifier: rollbackRolloutDeployment
                  type: K8sRollingRollback
                  timeout: 10m
                  spec:
                    pruningEnabled: false
        tags: {}
        failureStrategies:
          - onFailure:
              errors:
                - AllErrors
              action:
                type: StageRollback
        when:
          pipelineStatus: Success
```

</details>

In this pipeline, the step `ShellScript_1` runs only if the environment name is `harnessdevenv`.

When you select **Run**, you are prompted to provide a value for your environment at runtime. In this case, suppose you select the value as `harnessdevenv`:

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-f8c8d617667eb814af2c2f420b0aae5a08ac83f6%2Funresolved_runtime_input.png?alt=media)

The step Conditional Execution does not skip, and the variable resolves to true.

![](https://3694223630-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fy1JhZ4oKIppwY7d5AhPj%2Fuploads%2Fgit-blob-fdc21c9285d67f2473c0c99732515a589ef063ec%2Funresolved_expressio_true_1.png?alt=media)

In this case, the deploy stage first started the **Service** step and then fetched the environment and infrastructure information. Afterwards, it proceeded with the execution of step `ShellScript_1`. Before executing this step, the pipeline had information about the environment, and it checked if the environment name is `harnessdevenv`. In this case, it was true, so the step was executed. If it was false, the step would be skipped, but the variable would still resolve.

***

## Next steps

* [Step and stage failure strategy references](/continuous-delivery/use-continuous-delivery/cd-building-blocks/executions/step-failure-strategy-settings.md): Combine failure strategies with Conditional Execution safely.
* [Harness variables](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables): Build JEXL conditions from pipeline and stage expressions.
* [Fixed values, runtime inputs, and expressions](https://developer.harness.io/docs/platform/variables-and-expressions/runtime-inputs): Understand which values resolve before a stage runs.

{% @harness-feedback/feedback %}
