Skip to content

Latest commit

 

History

History
388 lines (309 loc) · 16.5 KB

0045-whenexpressions-in-finally-tasks.md

File metadata and controls

388 lines (309 loc) · 16.5 KB
status title creation-date last-updated authors
implemented
WhenExpressions in Finally Tasks
2021-01-21
2021-06-03
@jerop

TEP-0045: WhenExpressions in Finally Tasks


Summary

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.

Motivation

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.

Goals

  • Improve the reusability of Tasks by improving the guarding of Finally Tasks at authoring time.
  • Enable guarding execution of Finally Tasks using WhenExpressions.

Non-Goals

  • Enabling guarding Finally Tasks based on execution status of other Finally Tasks.

Proposal

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.

Using Execution Status

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
      # […]

Using Results

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.

Using Parameters

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.

User Experience

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.

Performance

WhenExpressions efficiently evaluate the execution criteria without spinning up new pods.

Test Plan

  • unit tests
  • end-to-end tests

Design Evaluation

  • Reusability: This proposal reuses an existing component, WhenExpressions, to guard Finally Tasks. Moreover, it improves the reusability of Tasks by enabling specifying guards explicitly and avoiding representing them in the Tasks's Steps.

  • Simplicity: Using WhenExpressions to guard the execution of Finally Tasks is much simpler than the workarounds that used Workspaces. It is also consistent with how we already guard the other Tasks.

Drawbacks

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.

Alternatives

  • Finally Tasks should not be guarded so that they're always "executed" as implied by the Finally terminology. However, users creating workarounds to support guarding Finally Tasks. In addition, we already allow skipping Finally Tasks they use uninitialized Results from skipped or failed Tasks.

  • Use Conditions to guard Finally Tasks. However, Conditions were deprecated and replaced with WhenExpressions, read further details in Conditions Beta TEP.

References