Files
runner/docs/adrs/1438-conditional-composite.md
Ferenc Hammerl 67ba8a7d42 Support Conditional Steps in Composite Actions (#1438)
* conditional support for composite actions

* Fix Conditional function evaluation

* Push launch.json temporarily

* Revert "Push launch.json temporarily"

* rename context

* Cleanup comments

* fix success/failure functions to run based on pre/main steps

* idea of step_status

* change to use steps context, WIP

* add inputs to possible if condition expressions

* use action_status

* pr cleanup

* Added right stages

* Test on stage in conditional functions

* Fix naming and formatting

* Fix tests

* Add success and failure L0s

* Remove comment

* Remove whitespace

* Undo formatting

* Add L0 for step-if parsing

* Add ADR

Co-authored-by: Thomas Boop <thboop@github.com>
2021-10-29 15:45:42 +02:00

4.0 KiB

ADR 1438: Support Conditionals In Composite Actions

Date: 2021-10-13

Status: Accepted

Context

We recently shipped composite actions, which allows you to reuse individual steps inside an action. However, one of the most requested features has been a way to support the if keyword.

Goals

  • We want to keep consistent with current behavior
  • We want to support conditionals via the if keyword
  • Our built in functions like success should be implementable without calling them, for example you can do job.status == success rather then success() currently.

How does composite currently work?

Currently, we have limited conditional support in composite actions for pre and post steps. These are based on the job status, and support keywords like always(), failed(), success() and cancelled(). However, generic or main steps do not support conditionals.

By default, in a regular workflow, a step runs on the success() condition. Which looks at the job status, sees if it is successful and runs.

By default, in a composite action, main steps run until a single step fails in that composite action, then the composite action is halted early. It does not care about the job status. Pre, and post steps in composite actions use the job status to determine if they should run.

How do we go forward?

Well, if we think about what composite actions are currently doing when invoking main steps, they are checking if the current composite action is successful. Lets formalize that concept into a "real" idea.

  • We will add an action_status field to the github context to mimic the job's context status.
    • We have an existing concept that does this action_path which is only set for composite actions on the github context.
  • In a composite action during a main step, the success() function will check if action_status == success, rather then job_status == success. Failure will work the same way.
    • Pre and post steps in composite actions will not change, they will continue to check the job status.

Nested Scenario

For nested composite actions, we will follow the existing behavior, you only care about your current composite action, not any parents. For example, lets imagine a scenario with a simple nested composite action

- Job
  - Regular Step
  - Composite Action
    - runs: exit 1
    - if: always()
      uses: A child composite action
        - if: success()
          runs: echo "this should print"
        - runs: echo "this should also print"
    - if: success()
      runs: echo "this will not print as the current composite action has failed already"
      

The child composite actions steps should run in this example, the child composite action has not yet failed, so it should run all steps until a step fails. This is consistent with how a composite action currently works in production if the main job fails but a composite action is invoked with if:always() or if: failure()

Other options explored

We could add the current_step_status to the job context rather then __status to the steps context, however this comes with two major downsides:

  • We need to support the field for every type of step, because its non trivial to remove a field from the job context once it has been added (its readonly)
    • For all actions besides composite it would only every be success
    • Its weird to have a current_step value on the job context
  • We also explored a __status on the steps context.
    • The __ is required to prevent us from colliding with a step with id: status
    • This felt wrong because the naming was not smooth, and did not fit into current conventions.

Consequences

  • github context has a new field for the status of the current composite action.
  • We support conditional's in composite actions
  • We keep the existing behavior for all users, but allow them to expand that functionality.