Conditional Workflows

JFrog Pipelines Documentation

ft:sourceType
Paligo

Conditional workflow in Pipelines enables you to choose if a step executes or skips based on certain conditions set for the previous upstream step. This means, when the workflow reaches a conditional step, it can choose different workflow paths based on the step’s status. This provides more flexibility in the execution logic of a pipeline.

Note

Conditional workflow can be applied to any Pipelines step.

Step Status Conditional Workflow

With the status conditional workflow, you can configure a step to execute only if an input step’s status, during its current run, is satisfied. You can configure any number of statuses for a step.

YAML Schema

    steps:
      - name: <step_name>
        type: <step_type>
        configuration:
                  allowFailure: boolean         #optional
          inputSteps:
            - name: <step_name>
              status:
                - <terminal_status>
                - <terminal_status>
                - <terminal_status>

Note

It is important to note that the status of an input step in the current run only is considered for conditional workflows. If a step is not part of the current run, it is always assumed that the condition for that input step is met.

Run Variable Conditional Workflow

Create a condition based on the values of add_run_variables environment variable, so that a step can be skipped based on dynamically set variables before it gets assigned to a node.

Note

When using a condition, boolean values must be enclosed in quotes.

Examples:

  • condition: 'trigger == "true"'

  • condition: "trigger == 'true'"

  • condition: trigger == 'true'

  • condition: trigger == "true"

YAML Schema

    steps:
      - name: <step_name>
        type: <step_type>
        execution:
          onExecute:
            - add_run_variables 'key=value'
      - name: <step_name>
        type: <step_type>
        configuration:
          condition: 'key == value' // Any logical boolean expression that results in a boolean
          inputSteps:
            - name: <step_name>
Example
pipelines:
  - name: Example
    steps:
      - name: step1
        type: Bash
        execution:
          onExecute:
            - echo 'step1'
            - add_run_variables 'var1=1'
      - name: step2
        type: Bash
        configuration:
          condition: 'var1 == 1' // Any logical boolean expression that results to a boolean
          inputSteps:
            - name: step1
        execution:
          onExecute:
            - echo 'success'

In this example, when step2 is triggered during a run, it will check for the condition and wait until those are satisfied. If the condition is not satisfied, it will skip with a message. Note that step2 can also timeout while waiting for the execute conditions to be satisfied.

Adding Conditional Workflow for Steps

To add a conditional workflow for a step:

  1. In the inputSteps section of a step, add the status property.

  2. Add any of these values:

    • success

    • failure

    • error

    • cancelled

    • skipped

    • unstable

    • timeout

    Note

    Ensure that the values are in lowercase and use the same spelling as shown above. Any deviation from this will cause the pipeline source sync to fail.

    Example: In this example:

    • step_B has only one status: success

    • step_c has multiple statuses: failure, skipped, cancelled

          - name: step_A
            type: Bash
            configuration:
                      allowFailure: boolean         #optional
              inputSteps:
                - name: step_B
                  status:
                    - success
                - name: step_C
                  status:
                    - failure
                    - skipped
                    - cancelled
  3. Optional: If you do not want a particular step to contribute to the final status of the run, you can add allowFailure: true to the configuration section of that step. When this option is used, even when a step fails or is skipped, the final status of the run is not affected.

    For example, a pipeline contains two steps S1 and S2:

    167314299.png
    • Scenario 1: Step S2 is a cleanup step and its status is irrelevant. The overall run status should be determined by S1’s status and S2’s status should be ignored. In this case, add allowFailure: true to S2, since this is purely a cleanup step and only S1’s status should be taken into consideration.

    • Scenario 2: Step S1 has been configured to fail as part of the workflow. However S2 runs even if S1 fails and the run is not to be considered a failure. The run’s final status should mirror S2’s status since S1’s status does not interrupt the flow. In this case, add allowFailure: true to S1 since S1’s failure is a known possibility and expected, and that should not affect the final status of the run.

For more examples, see allowFailure Examples.

Viewing Run Logs

When you run a pipeline, in addition to the other logs, the logs for steps with conditional workflow provide information about the skipped steps.

To view these logs, go to the Pipeline Run Logs view, click the skipped step to display the logs for the current run.

conditional_1a.png

Examples

Example 1

In this example:

  • Step B is triggered only if step A succeeds (default behavior), and step C is triggered only if step A is in failed, error, or timeout status.

  • Step B does not need any special configuration as the default behavior is to trigger a dependent step if the previous step succeeds.

  • Step A also does not need any special configuration since the step itself does not decide the downstream workflow path.

conditional_workflow_1ba.png

YAML

  - name: demo_conditional
    steps:
      - name: step_A
        type: Bash
        configuration:
          inputResources:
            - name: script_conditional
        execution:
          onExecute:
            - echo "Executing step_A"
            - printenv
     
      - name: step_B
        type: Bash
        configuration:
          inputSteps:
            - name: step_A
        execution:
          onExecute:
            - echo "Executing step_B"
            - printenv

      - name: step_C
        type: Bash
        configuration:
          inputSteps:
            - name: step_A
              status:
                - failure
                - error
                - timeout
        execution:
          onExecute:
            - echo "Executing step_C"
            - printenv
Example 2

In this example, Step S is triggered if Step Q succeeds and Step R fails. However, if both Step Q and Step R succeed or fail during the run, Step S is not triggered and it is skipped.

conditional_workflow_1ca.png

YAML

      - name: step_S
        type: Bash
        configuration:
          inputSteps:
            - name: step_Q
              status:
                - success
            - name: step_R
              status:
                - failure
        execution:
          onExecute:
            - echo "Executing step_S"
            - printenv
Example 3

In this example, Step O is triggered if Step M succeeds and Step N fails. However, since Step N is not part of the current run, Step O is triggered when Step M succeeds and Step N's status is ignored.

conditional_workflow_1db.png

YAML

      - name: step_O
        type: Bash
        configuration:
          inputSteps:
            - name: step_M
              status:
                - success
            - name: step_N
              status:
                - failure
        execution:
          onExecute:
            - echo "Executing step_O"
            - printenv
Example 4 - Using Environment Variable

The step_<inputStepName>_statusName, which is an environment variable that is automatically made available at runtime, can be used in conjunction with conditional workflows. This step_<inputStepName>_statusName environment variable is useful for fetching the status of any input step, especially when working with Jenkins.

YAML

resources:
  - name: script_gh
    type: GitRepo
    configuration:
      path: jfrog/sample-script
      gitProvider: myGithub
      branches:
        include: ^{{gitBranch}}$

pipelines:     
  - name: simple_jenkins_demo
    steps:
      - name: jenkins
        type: Jenkins
        configuration:
          inputResources:
            - name: script_gh
          jenkinsJobName: testPipeline
          integrations:
            - name: myJenkins
      
      - name: step_A
        type: Bash
        configuration:
          inputSteps:
            - name: jenkins
              status:
                - failure
                - error
                - timeout
        execution:
          onExecute:
            - echo "Executing step_A"
            - if [ $step_jenkins_statusName == "failure" ]; then  echo "Do something"; fi
            - if [ $step_jenkins_statusName == "error" ]; then  echo "Do something else"; fi
     
      - name: simple_conditional_B
        type: Bash
        configuration:
          inputSteps:
            - name: jenkins
              status:
                - failure
                - error
        execution:
          onExecute:
            - echo "Executing simple_conditional_B"
            - printenv

allowFailure Examples

Example 1

Step1 is configured for success and step2 for failure. Step2 is allowed to run when step1 fails and the final status of the run is success.

pipelines:
  - name: PIPE_9455_Workflow_03
    steps:
      - name: step1
        type: Bash
        execution:
          onExecute:
            - echo 'step1'
      - name: step2
        type: Bash
        configuration:
          allowFailure: true
          inputSteps:
          - name: step1
            status:
              - success
              - error
              - failure
              - timeout
        execution:
          onExecute:
            - echo 'success'
            - exit 1
Example 2

Step1 is configured for failure and step2 for success. Step2 is allowed to run when step1 fails and the final status of the run is success.

pipelines:
  - name: PIPE_9455_Workflow_05
    steps:
      - name: step1
        type: Bash
        configuration:
          allowFailure: true
        execution:
          onExecute:
            - echo 'step1'
            - exit 1
      - name: step2
        type: Bash
        configuration:
          inputSteps:
          - name: step1
            status:
              - success
              - error
              - failure
              - timeout
        execution:
          onExecute:
            - echo 'success'
Example 3

Step1 is configured for success and step2 for failure. When triggered, the final status of the run is failure.

pipelines:
  - name: PIPE_9455_Workflow_03
    steps:
      - name: step1
        type: Bash
        configuration:
          allowFailure: true
        execution:
          onExecute:
            - echo 'step1'
      - name: step2
        type: Bash
        configuration:
          inputSteps:
          - name: step1
            status:
              - success
              - error
              - failure
              - timeout
        execution:
          onExecute:
            - echo 'failure'
            - exit 1