pipeline icon indicating copy to clipboard operation
pipeline copied to clipboard

Dependent Task after Task with when condition are skipped

Open Allda opened this issue 1 year ago • 9 comments

Expected Behavior

Hello, I am building a pipeline with a conditional series of tasks that use the same when condition, after that series of tasks there is one or more other tasks that don't have the condition.

Simplified task schema looks like this

A -> B -> C

where A and B use the condition given by the pipeline argument. At the same time, B uses the output of A as an input parameter.

I expect the C is triggered regardless of A or B but as shown bellow this is no the case and if A and B are skipped the C is also skipped.

Actual Behavior

Based on the pipeline argument A and B are skipped as expected, but C is also skipped which is unexpected. Skipped reasons are the following: A - When Expressions evaluated to false B - Results were missing < -- This task uses when and should be also skipped the same way as task A C - Parent Tasks were skipped

Steps to Reproduce the Problem

  1. Create the following task and pipeline
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: basic-task
spec:
  params:
    - default: Hello
      name: appName
      type: string
  results:
    - name: my-result
      type: string
  steps:
    - image: registry.redhat.io/ubi7/ubi-minimal
      name: ''
      resources: {}
      script: |

        echo $(inputs.params.appName)

        echo $(inputs.params.appName) > $(results.my-result.path)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: when
spec:
  params:
    - default: foo
      name: param1
      type: string
  tasks:
    - name: basic-task
      params:
        - name: appName
          value: Hello
      taskRef:
        kind: Task
        name: basic-task
      when:
        - input: $(params.param1)
          operator: in
          values:
            - bar
    - name: basic-task-2
      params:
        - name: appName
          value: $(tasks.basic-task.results.my-result)
      runAfter:
        - basic-task
      taskRef:
        kind: Task
        name: basic-task
      when:
        - input: $(params.param1)
          operator: in
          values:
            - bar
    - name: basic-task-3
      params:
        - name: appName
          value: Hello
      runAfter:
        - basic-task-2
      taskRef:
        kind: Task
        name: basic-task

  1. Execute pipeline with default params

Additional Info

Client Version: 4.14.6 Kustomize Version: v5.0.1 Server Version: 4.13.31 Kubernetes Version: v1.26.13+77e61a2

  • Tekton Pipeline version:

Client version: 0.33.0 Chains version: v0.16.1 Pipeline version: v0.47.6 Triggers version: v0.24.2 Operator version: v0.67.3

Allda avatar Feb 16 '24 11:02 Allda

I once encountered a similar problem, and I suspect it is related to the status "Results were missing" in Phase B. After all, after skipping Phase A, Phase B still made a judgment on whether to execute.

l-qing avatar Feb 17 '24 01:02 l-qing

I'm not sure if this behavior is by design or a bug.

Relevant code:

https://github.com/tektoncd/pipeline/blob/123f4a211df298ac28dc18df2ec58701c9ffe842/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go#L306-L319

https://github.com/tektoncd/pipeline/blob/123f4a211df298ac28dc18df2ec58701c9ffe842/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go#L367-L388

https://github.com/tektoncd/pipeline/blob/123f4a211df298ac28dc18df2ec58701c9ffe842/pkg/apis/pipeline/v1/pipelinerun_types.go#L550-L565

l-qing avatar Feb 17 '24 01:02 l-qing

I think this is the relevant section of the docs on when expressions: https://tekton.dev/docs/pipelines/pipelines/#guarding-a-task-only

When when expressions evaluate to False, the Task will be skipped and:

  • The ordering-dependent Tasks will be executed
  • The resource-dependent Tasks (and their dependencies) will be skipped because of missing Results from the skipped parent Task.

Specifically the last point.

Also from the example just after that:

slack-msg will be skipped because it is missing the approver Result from manual-approval dependents of slack-msg would have been skipped too if it had any of them

As far as I understand this matches the behaviour you're describing so is working as designed.

AlanGreene avatar Feb 17 '24 01:02 AlanGreene

I have spent last several days reading the documentation about how the conditional Tekton task works so I understand why this is happening, but on the other hand if a task depends on the previous one (B depends on A) and B is is not executed due to when condition should this be also blocking and skipping a rest of the pipeline? The missing results from A used in B as params are not needed because the B is skipped.

Would you happen to have any suggestions on how to workaround this? The usecase for this is when a pipeline contains a series of task that depends on each other and are controlled by input parameter. In such a case with a current behavior, the pipeline always skips the rest of the pipeline even though there are no missing data for dependencies.

Allda avatar Feb 19 '24 09:02 Allda

@AlanGreene @l-qing Do you know if this issue can be workaround somehow until we get any official conclusion of this issue?

Allda avatar Feb 28 '24 10:02 Allda

I checked the code briefly and I think moving skipBecauseWhenExpressionsEvaluatedToFalse higher in the switch hierarchy and giving it higher priority would resolve this issue. Is there any reason why it is below skipBecauseResultReferencesAreMissing and skipBecauseParentTaskWasSkipped ?

https://github.com/tektoncd/pipeline/blob/123f4a211df298ac28dc18df2ec58701c9ffe842/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go#L309-L332

Allda avatar Feb 28 '24 10:02 Allda

@Allda did you get anywhere with this? I think we are facing the same issue.

willejs-ec avatar Jun 26 '24 10:06 willejs-ec

@willejs-ec Unfortunately I haven't. Due to this limitation, I wasn't able to use any when condition for tasks that have a common when condition and depend on each other. The only workaround I found was to put the condition inside of the task into the actual task code. This solution however makes the pipeline flow harder to read and forces a pipeline to create additional pods that are not doing any useful work and take resources and execution time.

Allda avatar Jun 27 '24 07:06 Allda