title | authors | creation-date | last-updated | status | |
---|---|---|---|---|---|
Conditions Beta |
|
2020-07-22 |
2021-06-03 |
implemented |
- Summary
- Background
- Motivation
- Requirements
- Proposal
- Test Plan
- Alternatives
- Upgrade & Migration Strategy
Original Design Doc in Google Docs, visible to members of tekton-dev@: https://docs.google.com/document/d/1kESrgmFHnirKNS4oDq3mucuB_OycBm6dSCSwRUHccZg/edit?usp=sharing
Conditions
is a CRD used to specify a criteria to determine whether or not a Task
executes. When other Tekton resources were migrated to beta, it remained in alpha because it was missing features needed by users.
After analyzing the feature requests and discussing with users, we have identified that the most critical gaps in Conditions
are simplicity, efficiency, skipping and status. We want to address these gaps so that it can work well with the other Pipeline
resources and users can count on its stability.
We will refer to Conditions
as Guards
because they determine if a Task
executes, not if/else as would be expected from a Condition
; more details on Guards
vs Conditions
naming can be found in this issue.
We propose:
- For simplicity, we propose deprecating the separate
Conditions
CRD and usingTasks
to produce theResults
needed to evaluate whether a dependentTask
executes. - For efficiency, we propose using string expressions through
When Expressions
to perform simple checks without spinning up newPods
; they can operate on previousTask's Results
,Parameters
, among other Tekton resources. - By deprecating
Conditions
CRD and usingWhen Expressions
, we can distinguish failed status from evaluating toFalse
.
We address skipping separately in TEP-0059: Skipping Strategies.
Conditions
is a custom resource that enables users to specify a criteria to determine whether or not a Task
executes. Its critical component is the Check
, which specifies a Step
, which is a Container
that evaluates a Condition
. If the container runs and exits with code 0, the Condition
evaluates as True
, otherwise it evaluates as False
.
With this design, users provide an image and Tekton runs it in a Pod
to check the Condition
, thus giving users flexibility to use whichever language. Conditions
actually manifest themselves as TaskRuns
that are handled differently from other TaskRuns
. For example, when a Condition
evaluates as False
, the TaskRun
from the Condition
fails but it does not cause the whole Pipeline
to fail, unlike the other TaskRuns
.
Users can specify Conditions
and reference them in Tasks
and Pipelines
as such:
apiVersion: tekton.dev/v1alpha1
kind: Condition
metadata:
name: file-exists
spec:
params:
- name: 'path'
resources:
- name: workspace
type: git
check:
image: alpine
script: 'test -f $(resources.workspace.path)/$(params.path)'
---
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: conditional-pipeline
spec:
resources:
- name: source-repo
type: git
params:
- name: path
default: 'README.md'
tasks:
- name: first-create-file
taskRef:
name: create-readme-file
resources:
outputs:
- name: workspace
resource: source-repo
- name: then-check
conditions:
- conditionRef: file-exists
params:
- name: path
value: '$(params.path)'
resources:
- name: workspace
resource: source-repo
from: [first-create-file]
taskRef:
name: echo-file-exists
For further information on Conditions
, read the documentation, view examples and review its uses in Tekton plumbing.
- Checking if the name of a git branch matches
- Checking if the
Result
of a previousTask
is as expected - Checking if a git file has changed in the previous commits
- Checking if an image exists in the registry
- Checking if the name of a CI job matches
- Argo:
Workflows
support conditional execution using a when property to specify whether to run or skip aStep
(example). - Concourse:
Jobs
specify theSteps
to execute when theJob
succeeds, fails, errors or aborts; but it has no built-in conditionals construct to determine if aJob
should execute. - Jenkins: Uses Conditional BuildStep Plugin enables
Conditions
which are defined by Run Condition, which has some built-in conditions, e.g. always, never, and file exists/match. - Drone : Supports Pipeline Conditions for including/excluding git branches, and Step Conditions which uses the
when
syntax. Documentation. - Spinnaker: Uses string expressions,
Stages
only run when expressions evaluate toTrue
.
Tekton users have made many feature requests for Conditions
that have been documented in this experience report. We have categorized the challenges that users experience when using Conditions
into the specific focus areas of simplicity, efficiency and skipping which we will address in this proposal.
Conditions
actually manifest themselves as Tasks
but are implemented as a separate CRD which makes them complex. Maintaining the separate Condition CRD takes extra and unnecessary effort, given that it's really a Task
underneath. We prefer to reuse existing components when possible.
Checking Conditions
is slow and expensive because it spins up new Pods
to evaluate each Condition
. For example, Tekton dogfooding has been heavily using Conditions
to decide what to run e.g only run this branch if it contains a specific type of file. These small checks add up such that many pods are used to check Conditions
and it becomes slow and expensive. Even worse, we don't have a conditional branching construct (if/else or switch), so users have to implement and execute opposite Conditions
which makes it even slower and more expensive. This can also be a problem in terms of the resource limits, requests, quotas and LimitRanges.
When a Condition
fails, the guarded Task
and its branch (dependent Tasks
) are skipped. A Task
is dependent on and in the branch of another Task
as specified by ordering using runAfter
or by resources using Results
, Workspaces
and Resources
. In some use cases of Conditions
, when a Condition
evaluates to False
, users need to skip the guarded Task
only and allow dependent Tasks
to execute. An example use case is when there’s a particular Task
that a Pipeline wants to execute when the git branch is dev/staging/qa, but not when it’s the main/master/prod branch. Another use case is when a user wants to send out a notification whether or not a parent guarded Task
was executed, as described in this issue.
It is currently difficult to distinguish between a Task
that was skipped due to Condition
evaluating as False
and a Task
that failed. This is because we use exit codes in Check
as described in Conditions section above and reuse ConditionSucceeded
from Knative which can have the following states: True
, False
or Unknown
. When a Task
either fails or is skipped from Condition
evaluating to False
, we mark ConditionSucceeded
as False
.
- Users need a way to specify logic -
Guards
- to determine if aTask
should execute or not. - Users need a way to specify whether to execute dependent
Tasks
whenGuards
of a parentTask
evaluate toFalse
. - Users should be able to specify multiple
Guards
for a givenTask
. - Users should be able to use
Outputs
from parentTasks
and static input to specifyGuards
. - Users should be able to distinguish between a
Guard
failing (such as when missing resources) and aGuard
evaluating toFalse
.
We propose:
- For simplicity, we propose deprecating the separate
Conditions
CRD and usingTasks
to produce theResults
needed to evaluate whether a dependentTask
executes. - For efficiency, we propose using string expressions through
When Expressions
to perform simple checks without spinning up newPods
; they can operate on previousTask's Results
,Parameters
, among other Tekton resources. - By deprecating
Conditions
CRD and usingWhen Expressions
, we can distinguish failed status from evaluating toFalse
.
We address skipping separately in TEP-0059: Skipping Strategies.
As discussed in the background section, Conditions
manifest themselves as Tasks
. We want to keep Tekton as simple as possible by reusing existing components. So we propose phasing out the separate Conditions
CRD and eventually deprecating it. In place of Conditions
, we propose using Tasks
produce to Results
that we can use to specify Guards
using When Expressions
in subsequent Tasks
, as described in Efficiency section below. Thus, we won’t have Conditions
to migrate to beta and won’t have to maintain the separate Conditions
CRD.
In the example of checking whether a file exists, the Task
that would replace the Condition
would be specified as such:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: file-exists
spec:
params:
- name: path
workspaces:
- name: source
results:
- name: exists
description: boolean indicating whether the file exists
steps:
- name: check-file-exists
image: alpine
script: |
if [ -f $(workspaces.source.path)/$(params.path) ]; then
echo true | tee /tekton/results/exists
else
echo false | tee /tekton/results/exists
fi
To improve the efficiency of guarded execution of Tasks
, we need to avoid spinning up new Pods
to check Guards
. We can use string expressions for Guard
checking, but we want to avoid adding an opinionated and complex expression language to the Tekton API to ensure Tekton can be supported by as many systems as possible.
We propose using a simple expression syntax When Expressions
(similar to Kubernetes' Match Expressions) to evaluate Guards
efficiently. The components of When Expressions
are Input
, Operator
and Values
:
Input
is the input for theGuard
checking which can be static inputs or outputs from parentTasks
, such asParameters
orResults
.Values
is an array of string values. TheValues
array must be non-empty. It can contain static values or variables (such asParameters
).Operator
represents anInput
's relationship to a set ofValues
.Operators
we will use inGuards
areIn
andNotIn
.
When we have more than one Guard
, the guarded Task
will be executed when all the Guards
evaluate to True
. Note that when a Guard
uses a resource from another Task
, such as a Result
, it introduces an implicit resource dependency that makes the guarded Task
dependent on the resource-producing Task
.
Here's how a user can specify a Guard
that executes on that Result
:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: file-exists
spec:
params:
- name: path
workspaces:
- name: source
results:
- name: exists
description: boolean indicating whether the file exists
steps:
- name: check-file-exists
image: alpine
script: |
if [ -f $(workspaces.source.path)/$(params.path) ]; then
echo true | tee /tekton/results/exists
else
echo false | tee /tekton/results/exists
fi
---
api: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: generate-file
spec:
workspaces:
- name: source-repo
params:
- name: path
default: 'README.md'
tasks:
- name: create-file
taskRef:
name: create-readme-file
workspaces:
- name: source
workspace: source-repo
- name: file-exists
taskRef:
name: file-exists
workspaces:
- name: source
workspace: source-repo
- name: echo-file-exists
when:
- input: '$(tasks.file-exists.results.exists)'
operator: In
values: ['true']
taskRef:
name: echo-file-exists
Other examples of Guards
using When Expressions
are:
input: $(params.branch)
operator: In
values: [‘main’]
---
input: $(params.branch)
operator: NotIn
values: [‘main’]
---
input: ‘false’
operator: In
values: [‘’]
We can explore adding more Operators later if needed, such as IsTrue
, IsFalse
, IsEmpty
and IsNotEmpty
. Kubernetes' Match Expressions
uses a comma separator as an AND
operator but it won't be supported in Tekton's When Expressions
(can be revisted later).
Add Skipped Tasks
section to the PipelineRunStatus
that contains a list of SkippedTasks
that contains a Name
field which has the PipelineTaskName
and a When Expressions
field which has a list of the resolved WhenExpressions
. Thus, users can know why a particular Task
was skipped. In addition, TaskRuns
from guarded Tasks
that execute because their WhenExpressions
evaluate to true would have the resolved WhenExpressions
included in the TaskRun
status.
In this example, the WhenExpressions
in skip-this-task
evaluate to False while the WhenExpressions
in run-this-task
evaluate to True:
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
Reason: Completed
Status: True
Type: Succeeded
Pipeline Spec:
Params:
Name: param
Type: string
Default: foo
Tasks:
Name: skip-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Night!"
When:
Input: $(params.param)
Operator: in
Values:
bar
Input: $(params.param)
Operator: notin
Values:
$(params.param)
Name: run-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When:
Input: $(params.param)
Operator: in
Values:
$(params.param)
Skipped Tasks:
Name: skip-this-task
When Expressions:
Input: foo
Operator: in
Values:
bar
Input: foo
Operator: notin
Values:
foo
Start Time: 2020-08-27T15:07:30Z
Task Runs:
pipelinerun-to-skip-task-run-this-task-r2djj:
Pipeline Task Name: run-this-task
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: All Steps have completed executing
Reason: Succeeded
Status: True
Type: Succeeded
Pod Name: pipelinerun-to-skip-task-run-this-task-r2djj-pod
Start Time: 2020-08-27T15:07:30Z
Steps:
Container: step-echo
Image ID: docker-pullable://ubuntu@sha256:6f2fb2f9fb5582f8b5
Name: echo
Terminated:
Container ID: docker://df348b8f64165fd15e3301095510
Exit Code: 0
Finished At: 2020-08-27T15:07:33Z
Reason: Completed
Started At: 2020-08-27T15:07:33Z
Task Spec:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When Expressions:
Input: foo
Operator: in
Values:
foo
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 2m29s PipelineRun
Normal Running 2m29s PipelineRun Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 1, Skipped: 1
Normal Succeeded 2m25s PipelineRun Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
These are examples of how the Conditions in Tekton dogfooding and their usage would be translated and used in the new design:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: check-git-files-changed
namespace: tektonci
annotations:
description: |
Succeeds if any of the files changed in the last N commits from the
revision defined in the git resource matches the regular expression
spec:
params:
- name: gitCloneDepth
description: Number of commits + 1
- name: regex
description: Regular expression to match files changed
resources:
- name: source
type: git
results:
- name: changed
description: Boolean that indicates whether a file changed
steps:
- name: check-git-files-changed
image: alpine/git
script: |
#!/bin/sh
set -ex
BACK="HEAD~$(( $(params.gitCloneDepth) - 1 ))"
cd $(resources.source.path)
if [ -z git diff-tree --no-commit-id --name-only -r HEAD $BACK | grep -E '$(params.regex)' ]; then
echo false | tee /tekton/results/changed
else
echo true | tee /tekton/results/changed
fi
---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: tekton-noop-check
namespace: tektonci
spec:
params:
- name: passorfail
description: Should the CI Job 'pass' or 'fail'
- name: message
description: Message to be logged in the CI Job
- name: gitCloneDepth
description: Number of commits in the change + 1
- name: fileFilterRegex
description: Names regex to be matched in the list of modified files
- name: checkName
description: The name of the GitHub check that this pipeline is used for
- name: gitHubCommand
description: The command that was used to trigger testing
resources:
- name: source
type: git
tasks:
- name: check-git-files-changed
params:
- name: gitCloneDepth
value: $(params.gitCloneDepth)
- name: regex
value: $(params.fileFilterRegex)
resources:
- name: source
resource: source
taskRef:
- name: check-git-files-changed
- name: check-name-matches
params:
- name: gitHubCommand
value: $(params.gitHubCommand)
- name: checkName
value: $(params.checkName)
resources:
- name: source
resource: source
taskRef:
- name: check-git-files-changed
- name: ci-job
when:
- input: "$(tasks.check-git-files-changed.results.changed)"
key: In
values: ["true"]
- input: "$(params.githubCommand)"
key: In
values: ["", "/test $(params.checkName)"]
taskRef:
name: tekton-noop
params:
- name: message
value: $(params.message)
- name: passorfail
value: $(params.passorfail)
resources:
inputs:
- name: source
resource: source
The When Expressions
providing In
and NotIn
Operators
may not cover some edge use cases of Guards
, however the design will be flexible to support other Operators
. Moreover, this design allows for exploring using CEL
through CustomTasks
.
- Provide unit tests and e2e tests for
When Expressions
with variedInputs
andValues
. - Provide unit tests and e2e tests for
whenSkipped
with variedTask
branches.
As discussed in the background section, Conditions
manifest themselves as Tasks
. We can phase out the separate Conditions
CRD and eventually deprecate it. In place of Conditions
, we can use Tasks
produce a Result
called Skip
with string values True
or False
-- to indicate whether the Task
it’s guarding will be executed or not. When a user provides another value, the Task
will evaluate it as an error. Thus, we won’t have Conditions
to migrate to beta and won’t have to maintain the separate Conditions
CRD. Moreover, the features supported by Tasks
become readily available to be used for guarded execution of Tasks
. Using Results
allows us to distinguish between when a Task
fails and when the Task
used as a Guard
evaluates to False
.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: file-exists
spec:
parameters:
- name: path
resources:
- name: workspace
type: git
results:
- name: skip
description: boolean indicating whether guarded Task should be skipped
steps:
- name: check-file-exists
image: alpine
script: |
if [ -f $(resources.workspace.path)/$(params.path) ]; then
echo true | tee /tekton/results/skip
else
echo false | tee /tekton/results/skip
fi
---
api: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: generate-file
spec:
workspaces:
- name: source-repo
params:
- name: path
default: 'README.md'
tasks:
- name: create-file
taskRef:
name: create-readme-file
workspaces:
- name: source
workspace: source-repo
- name: echo-file-exists
when:
- name: check-file-exists
taskRef:
- name: file-exists
workspaces:
- name: source
workspace: source-repo
taskRef:
name: echo-file-exists
Initially, while still supporting Conditions
, we can use Tasks
used as Guards
. Users can use either the Conditions
list or Guards
list, but not both of them. Over time, we will phase out the Conditions
and support Guards
only.
If guarded execution of Tasks
is implemented using Tasks that produce Skip Result, we can then extend it to use CustomTasks
to build and experiment with using string expressions for simple Guards
. In Triggers, we use Common Expression Language for filtering using a CEL
interceptor. We can provide a CelRun CustomTask
, so that we experiment with CEL
without putting it into the Tekton API. After experimentation with CelRun
CustomTask
for a while, we will revisit whether we want to add it to the Tekton API.
An example using a CelRun
can be specified as shown below:
api: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: generate-file
spec:
workspaces:
- name: source-repo
params:
- name: path
default: 'README.md'
- name: branch
default: 'main'
tasks:
- name: create-file
taskRef:
name: create-readme-file
workspaces:
- name: source
workspace: source-repo
- name: echo-file-exists
when:
- name: check-file-exists
taskRef:
- name: file-exists
workspaces:
- name: source
workspace: source-repo
- name: branch-is-main
taskSpec:
apiVersion: custom.dev/v1beta1
kind: CelRun
spec:
eval: '$(params.branch)' == ‘main’
taskRef:
name: echo-file-exists
When the Pipeline
executes, it’ll create a CelRun
object, and we’ll provide a controller
to interpret and execute the CelRun
. We can also experiment with using other languages, like bash
, scriptmode
, jsonpath
. If we pursue this later, we'll write a separate TEP.
In Triggers, we use CEL for filtering to avoid spinning up a new pod. Similarly, we can choose a particular expression language - Common Expression Language - and use it to evaluate simple Guards
efficiently in the controller.
api: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: generate-file
spec:
workspaces:
- name: source-repo
params:
- name: path
default: 'README.md'
- name: branch
default: 'main'
tasks:
- name: create-file
taskRef:
name: create-readme-file
workspaces:
- name: source
workspace: source-repo
- name: echo-file-exists
when:
- name: check-file-exists
taskRef:
- name: file-exists
workspaces:
- name: source
workspace: source-repo
- name: branch-is-main
eval: '$(params.branch)' == ‘main’
taskRef:
name: echo-file-exists
To make it flexible, similarly to Triggers which uses language interceptors that's pluggable, we can provide a CEL
interceptor out of the box and, if needed, users can add or bring their own interceptors to use other languages.
Add Skipped Tasks
section to the PipelineRunStatus
that contains a list of SkippedTasks
that contains a Name
field which has the PipelineTaskName
. The WhenExpressions
that made the Task
skipped can be found in the PipelineSpec
, the Parameter
variables used can be found in the PipelineSpec
and the Results
used from previous Tasks
can be found in the relevant TaskRun
. It may be more work for users to reverse-engineer to identify why a Task
was skipped, but gives us the benefit of significantly reducing the PipelineRunStatus
compared to what we currently have with Conditions
.
In this example, the WhenExpressions
in skip-this-task
evaluate to False while the WhenExpressions
in run-this-task
evaluate to True:
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
Reason: Completed
Status: True
Type: Succeeded
Pipeline Spec:
Params:
Name: param
Type: string
Default: foo
Tasks:
Name: skip-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Night!"
When:
Input: $(params.param)
Operator: in
Values:
bar
Input: $(params.param)
Operator: notin
Values:
$(params.param)
Name: run-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When:
Input: $(params.param)
Operator: in
Values:
$(params.param)
Skipped Tasks:
Name: skip-this-task
Start Time: 2020-08-27T15:07:30Z
Task Runs:
pipelinerun-to-skip-task-run-this-task-r2djj:
Pipeline Task Name: run-this-task
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: All Steps have completed executing
Reason: Succeeded
Status: True
Type: Succeeded
Pod Name: pipelinerun-to-skip-task-run-this-task-r2djj-pod
Start Time: 2020-08-27T15:07:30Z
Steps:
Container: step-echo
Image ID: docker-pullable://ubuntu@sha256:6f2fb2f9fb5582f8b5
Name: echo
Terminated:
Container ID: docker://df348b8f64165fd15e3301095510
Exit Code: 0
Finished At: 2020-08-27T15:07:33Z
Reason: Completed
Started At: 2020-08-27T15:07:33Z
Task Spec:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 2m29s PipelineRun
Normal Running 2m29s PipelineRun Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 1, Skipped: 1
Normal Succeeded 2m25s PipelineRun Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
For skipped Tasks
, create a TaskRun
object with ConditionType
ConditionSucceeded
with status ConditionTrue
and reason Skipped
because it has successfully skipped the Task
based on the WhenExpressions
. The message would have further detail that the Task
was skipped because WhenExpressions
were evaluated to False
. However, it might be confusing that we create a TaskRun
object to record status for a Task
that was skipped and it also creates a larger PipelineRunStatus
than using Skipped Tasks
section.
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
Reason: Completed
Status: True
Type: Succeeded
Pipeline Spec:
Params:
Name: param
Type: string
Default: foo
Tasks:
Name: skip-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Night!"
When:
Input: $(params.param)
Operator: in
Values:
bar
Input: $(params.param)
Operator: notin
Values:
$(params.param)
Name: run-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When:
Input: $(params.param)
Operator: in
Values:
$(params.param)
Start Time: 2020-08-27T15:07:30Z
Task Runs:
pipelinerun-to-skip-task-run-this-task-r2djj:
Pipeline Task Name: run-this-task
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: All Steps have completed executing
Reason: Succeeded
Status: True
Type: Succeeded
Pod Name: pipelinerun-to-skip-task-run-this-task-r2djj-pod
Start Time: 2020-08-27T15:07:30Z
Steps:
Container: step-echo
Image ID: docker-pullable://ubuntu@sha256:6f2fb2f9fb5582f8b5
Name: echo
Terminated:
Container ID: docker://df348b8f64165fd15e3301095510
Exit Code: 0
Finished At: 2020-08-27T15:07:33Z
Reason: Completed
Started At: 2020-08-27T15:07:33Z
Task Spec:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When Expressions:
Input: foo
Operator: in
Values:
foo
pipelinerun-to-skip-task-skip-this-task-r2djj:
Pipeline Task Name: skip-this-task
Status:
Conditions:
Message: WhenExpressions for pipeline task skip-this-task evaluated to false and was skipped
Reason: Skipped
Status: True
Type: Succeeded
When Expressions:
Input: foo
Operator: in
Values:
bar
Input: foo
Operator: notin
Values:
foo
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 2m29s PipelineRun
Normal Running 2m29s PipelineRun Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 1, Skipped: 1
Normal Succeeded 2m25s PipelineRun Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
Add a new ConditionType
called ConditionSkipped
. For skipped Tasks
, create a TaskRun
object with ConditionType
ConditionSkipped
with status ConditionTrue
and reason WhenExpressionsEvaluatedToFalse
. However, it might be confusing that we create a TaskRun
object to record status for a Task
that was skipped and it also creates a larger PipelineRunStatus
than using Skipped Tasks
section.
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
Reason: Completed
Status: True
Type: Succeeded
Pipeline Spec:
Params:
Name: param
Type: string
Default: foo
Tasks:
Name: skip-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Night!"
When:
Input: $(params.param)
Operator: in
Values:
bar
Input: $(params.param)
Operator: notin
Values:
$(params.param)
Name: run-this-task
Task Spec:
Metadata:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When:
Input: $(params.param)
Operator: in
Values:
$(params.param)
Start Time: 2020-08-27T15:07:30Z
Task Runs:
pipelinerun-to-skip-task-run-this-task-r2djj:
Pipeline Task Name: run-this-task
Status:
Completion Time: 2020-08-27T15:07:34Z
Conditions:
Last Transition Time: 2020-08-27T15:07:34Z
Message: All Steps have completed executing
Reason: Succeeded
Status: True
Type: Succeeded
Pod Name: pipelinerun-to-skip-task-run-this-task-r2djj-pod
Start Time: 2020-08-27T15:07:30Z
Steps:
Container: step-echo
Image ID: docker-pullable://ubuntu@sha256:6f2fb2f9fb5582f8b5
Name: echo
Terminated:
Container ID: docker://df348b8f64165fd15e3301095510
Exit Code: 0
Finished At: 2020-08-27T15:07:33Z
Reason: Completed
Started At: 2020-08-27T15:07:33Z
Task Spec:
Steps:
Image: ubuntu
Name: echo
Resources:
Script: echo "Good Morning!"
When Expressions:
Input: foo
Operator: in
Values:
foo
pipelinerun-to-skip-task-skip-this-task-r2djj:
Pipeline Task Name: skip-this-task
Status:
Conditions:
Message: WhenExpressions for pipeline task skip-this-task evaluated to false and was skipped
Reason: WhenExpressionsEvaluatedToFalse
Status: True
Type: Skipped
When Expressions:
Input: foo
Operator: in
Values:
bar
Input: foo
Operator: notin
Values:
foo
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 2m29s PipelineRun
Normal Running 2m29s PipelineRun Tasks Completed: 0 (Failed: 0, Cancelled 0), Incomplete: 1, Skipped: 1
Normal Succeeded 2m25s PipelineRun Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 1
- We will implement the design while still supporting the
Conditions
CRD. - We will gather user feedback and use it to inform phasing out
Conditions
CRD. - In addition, we will add common examples in the
Catalog
to help users migrate easily.