status | title | creation-date | last-updated | authors | |
---|---|---|---|---|---|
implemented |
WhenExpressions in Finally Tasks |
2021-01-21 |
2021-06-03 |
|
Users can guard execution of Tasks
using WhenExpressions
, but that is not supported in Finally Tasks
. This TEP
describes the need for supporting WhenExpressions
in Finally Tasks
not only to provide efficient guarded execution
but also to improve the reusability of Tasks
. Given we've recently added support for Results
and Status
in
Finally Tasks
, this is an opportune time to enable WhenExpressions
in Finally Tasks
.
Currently, users cannot guard the execution of Finally Tasks
so they are always executed.
Users may want to guard the execution of Finally Tasks
based on Results
from other Tasks
.
Moreover, now that the execution status of Tasks
is accessible in Finally Tasks
,
they may also want to guard the execution of Finally Tasks
based on the execution status of other Tasks
.
An example use case is a Pipeline
author wants to send a notification, such as posting on Slack using this catalog task,
when a certain Task
in the Pipeline
failed. To do this, one user has had to use a workaround using Workspaces
that
they describe in this thread.
In addition, needing the workaround prevents the user from reusing the Slack catalog task as further described in this issue.
We already guard Tasks
using WhenExpressions
,
which efficiently evaluate the criteria of executing Tasks
. We propose supporting using WhenExpressions
to guard
the execution of Finally Tasks
as well.
- Improve the reusability
of
Tasks
by improving the guarding ofFinally Tasks
at authoring time. - Enable guarding execution of
Finally Tasks
usingWhenExpressions
.
- Enabling guarding
Finally Tasks
based on execution status of otherFinally Tasks
.
To improve reusability and support guarding of Tasks
in Finally
, we propose enabling WhenExpressions
in Finally Tasks
. Similar to in non-finally Tasks
, the WhenExpressions
in Finally Tasks
can operate on static inputs or
variables such as Parameters
, Results
and Execution Status
through variable substitution.
If the WhenExpressions
evaluate to True
, the Finally Task
would be executed. If the WhenExpressions
evaluate to
False
, the Finally Task
would be skipped and included in the list of Skipped Tasks
section of the Status
.
Moreover, the Pipeline
will exit with Completion
instead of Success
, as described in a similar scenario in the docs.
Note that this proposal does not affect the scheduling of Finally Tasks
, they will still be executed in parallel after
the other Tasks
are done.
Users would be able to solve for the example use case described in Motivation, where a user wants to send
a Slack notification using an Execution Status
(when a Task
fails), as demonstrated using golang-build
and send-to-channel-slack
Catalog Tasks
:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: pipelinerun-
spec:
pipelineSpec:
tasks:
- name: golang-build
taskRef:
name: golang-build
# […]
finally:
- name: notify-build-failure # executed only when build task fails
when:
- input: $(tasks.golang-build.status)
operator: in
values: ["Failed"]
taskRef:
name: send-to-slack-channel
# […]
Users can use Results
in the WhenExpressions
in Finally Tasks
, as demonstrated using boskos-acquire
and boskos-release
Catalog Tasks
:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: pipelinerun-
spec:
pipelineSpec:
tasks:
- name: boskos-acquire
taskRef:
name: boskos-acquire
- name: use-resource
# […]
finally:
- name: boskos-release # executed only when leased resource is phonetic-project
when:
- input: $(tasks.boskos-acquire.results.leased-resource)
operator: in
values: ["phonetic-project"]
taskRef:
name: boskos-release
# […]
If the WhenExpressions
in a Finally Task
use Results
from a skipped or failed non-finally Tasks
, then the
Finally Task
would also be skipped and be included in the list of Skipped Tasks
in the Status
, similarly to when
Results
in other parts of the Finally Task
.
We will validate the Result
references in the WhenExpressions
beforehand. If they are invalid (e.g. they don't
exist or there's a typo), the Pipeline
validation will fail upfront.
Users can use Parameters
in the WhenExpressions
in Finally Tasks
, as demonstrated using golang-build
and send-to-channel-slack
Catalog Tasks
:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: pipelinerun-
spec:
pipelineSpec:
params:
- name: enable-notifications
type: string
description: a boolean indicating whether the notifications should be sent
tasks:
- name: golang-build
taskRef:
name: golang-build
# […]
finally:
- name: notify-build-failure # executed only when build task fails and notifications are enabled
when:
- input: $(tasks.golang-build.status)
operator: in
values: ["Failed"]
- input: $(params.enable-notifications)
operator: in
values: ["true"]
taskRef:
name: send-to-slack-channel
# […]
params:
- name: enable-notifications
value: true
We will validate the Parameters
references in the WhenExpressions
beforehand. If they are invalid (e.g. they don't
exist or there's a typo), the Pipeline
validation will fail upfront.
Currently, users have to build workarounds using Workspaces
and make their Finally Tasks
's Steps
implement the
conditional execution. By supporting WhenExpressions
in Finally Tasks
, we will significantly improve the user
experience of guarding the execution of Finally Tasks
. Additionally, it makes it easier for users to reuse Tasks
including those provided in the Catalog.
WhenExpressions
efficiently evaluate the execution criteria without spinning up new pods.
- unit tests
- end-to-end tests
-
Reusability: This proposal reuses an existing component,
WhenExpressions
, to guardFinally Tasks
. Moreover, it improves the reusability ofTasks
by enabling specifying guards explicitly and avoiding representing them in theTasks
'sSteps
. -
Simplicity: Using
WhenExpressions
to guard the execution ofFinally Tasks
is much simpler than the workarounds that usedWorkspaces
. It is also consistent with how we already guard the otherTasks
.
One could argue that this proposal breaks the Finally
contract because a Finally Task
would not run when its
WhenExpressions
evaluate to False
. However, the PipelineRun
does attempt such Finally Tasks
and is explicitly
skipped, so it's considered ran
by the PipelineRun
Controller. Moreover, we are already failing Finally Tasks
that use Results
from failed or skipped Tasks
with validation failure.
-
Finally Tasks
should not be guarded so that they're always "executed" as implied by theFinally
terminology. However, users creating workarounds to support guardingFinally Tasks
. In addition, we already allow skippingFinally Tasks
they use uninitializedResults
from skipped or failedTasks
. -
Use
Conditions
to guardFinally Tasks
. However,Conditions
were deprecated and replaced withWhenExpressions
, read further details in Conditions Beta TEP.