Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WhenExpressions: support ANY match behavior #3591

Open
Tracked by #7415
bitsofinfo opened this issue Dec 3, 2020 · 20 comments
Open
Tracked by #7415

WhenExpressions: support ANY match behavior #3591

bitsofinfo opened this issue Dec 3, 2020 · 20 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature. lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness.

Comments

@bitsofinfo
Copy link

Feature request

The default behavior of:

If ALL the WhenExpressions evaluate to True

Needs a simple option to toggle the behavior to be:

If ANY of the WhenExpressions evaluate to True

Use case

I have a scenario where I have N spawned tasks, and if any ONE of their results have a particular value, I need something else to run.

@bitsofinfo bitsofinfo added the kind/feature Categorizes issue or PR as related to a new feature. label Dec 3, 2020
@jerop
Copy link
Member

jerop commented Dec 3, 2020

I have a scenario where I have N spawned tasks, and if any ONE of their results have a particular value, I need something else to run.

@bitsofinfo if possible, could you please share more specifics of this use case? it'd help to have an example of what the N tasks are doing and what the something else to run is

@bitsofinfo
Copy link
Author

pipeline kicks off 3 parallel deployments, if any one of them fails, they all have to get rolled back

@jerop
Copy link
Member

jerop commented Dec 3, 2020

pipeline kicks off 3 parallel deployments, if any one of them fails, they all have to get rolled back

thank you @bitsofinfo!

assuming that success/failure is indicated by a result, instead of task failure (that'd cause the pipeline to fail), can this use case be solved by checking that the failure status is in an array of the results from the tasks?

tasks:
- name: deploy-1
  taskSpec:
    results:
    - name: status
    ...
- name: deploy-2
  taskSpec:
    results:
    - name: status
    ...
- name: deploy-3
  taskSpec:
    results:
    - name: status
    ...
- name: rollback
  when:
  - input: failure
    operator: in
    values: 
    - "$(tasks.deploy-1.results.status)"
    - "$(tasks.deploy-2.results.status)"
    - "$(tasks.deploy-3.results.status)"
  taskSpec:
    ...

@bitsofinfo
Copy link
Author

thanks

Each of my deploy tasks outputs a result called last-exit-code and any code other than 0 is a failure. (i.e. 0=success, !=0 is failure)

so... i think this might work, w/ the current ALL behavior

  - input: "0"
    operator: notin
    values: 
    - "$(tasks.deploy-1.results.last-exit-code)"
    - "$(tasks.deploy-2.results.last-exit-code)"
    - "$(tasks.deploy-3.results.last-exit-code)"

will go try this. still, any behavior would be a nice option.

@jerop
Copy link
Member

jerop commented Dec 3, 2020

thanks

Each of my deploy tasks outputs a result called last-exit-code and any code other than 0 is a failure. (i.e. 0=success, !=0 is failure)

so... i think this might work, w/ the current ALL behavior

  - input: "0"
    operator: notin
    values: 
    - "$(tasks.deploy-1.results.last-exit-code)"
    - "$(tasks.deploy-2.results.last-exit-code)"
    - "$(tasks.deploy-3.results.last-exit-code)"

nice! glad you have a solution for the use case 😃

will go try this. still, any behavior would be a nice option.

the values field is an array so it can be used to represent any logic, however we can revisit supporting any if we get other ci/cd use cases that can't be solved otherwise

@bitsofinfo
Copy link
Author

thx!

@bitsofinfo
Copy link
Author

bitsofinfo commented Dec 4, 2020

actually... @jerop realizing that unfortunately this still wont work

example:

deploy-1 succeeds, last-exit-code = 0
deploy-2 succeeds, last-exit-code = 0
deploy-3 fails, last-exit-code = 1
deploy-4 fails, last-exit-code = 99

Will not pass as 0 is in the list

  when:
  - input: "0"
    operator: notin
    values: 
    - "$(tasks.deploy-1.results.last-exit-code)"
    - "$(tasks.deploy-2.results.last-exit-code)"
    - "$(tasks.deploy-3.results.last-exit-code)"
    - "$(tasks.deploy-4.results.last-exit-code)"

... and I can't do the inverse because the "input" is not necessarily known, the exit code could be anything !=0

  when:
  - input: "<exit code that is failure could be anything != 0>"
    operator: in
    values: 
    - "$(tasks.deploy-1.results.last-exit-code)"
    - "$(tasks.deploy-2.results.last-exit-code)"
    - "$(tasks.deploy-3.results.last-exit-code)"
    - "$(tasks.deploy-4.results.last-exit-code)"

@jerop
Copy link
Member

jerop commented Dec 4, 2020

is using last exit code as a result a workaround to avoid your pipeline failing or is it something you actually want?

if it's a workaround, maybe the setup we need for this use case is that:

in the meantime, i'd recommend changing your result to represent the success/failure instead of using the exit code directly (if exit code == 0, then result is success, otherwise result is failure) -- this would allow you to use the setup in #3591 (comment)

cc @bobcatfish @pritidesai

@bitsofinfo
Copy link
Author

I write last-exit-code and then analyze it to make decisions because various things have different failure reasons. It's something I actually want to be able to do vs hard failing the actual worker tasks themselves.

in any case, all I'm asking for is an "ANY" option for WhenExpressions. Would be simple to add. I'm just an advocate for making it as flexible as possible for the end-user, vs changing their implementation to adhere with limited evaluation capabilities of the framework itself. Similar to the arguments in #3468. Seems adding a config flag for WhenExpressions might be simpler than altering core fundamental dag behavior.

@jerop
Copy link
Member

jerop commented Dec 4, 2020

in any case, all I'm asking for is an "ANY" option for WhenExpressions. Would be simple to add. I'm just an advocate for making it as flexible as possible for the end-user, vs changing their implementation to adhere with limited evaluation capabilities of the framework itself.

we want to add features only when they're absolutely necessary and that's why we need to find use cases that can't be solved or that are challenging to solve, further described in the simplicity section of the design principles

adding is ANY may be easy but not simple

@pritidesai
Copy link
Member

@vincent-pli
Copy link
Member

I guess one use case we cannot satisfied:

  when:
  - input: success
    operator: in
    values: 
    - "$(tasks.deploy-1.results.status)"
    - "$(tasks.deploy-2.results.status)"
    - "$(tasks.deploy-3.results.status)"

3 parallel tasks, if one if them success, the 4th task will start to run.
but if one of the 3 task stuck, although another one already success, we still wait until timeout.

I means the requirements is: if any of the tasks success, do not wait others, the 4th should execute immediately. @jerop

@jerop
Copy link
Member

jerop commented Jan 21, 2021

I guess one use case we cannot satisfied:

  when:
  - input: success
    operator: in
    values: 
    - "$(tasks.deploy-1.results.status)"
    - "$(tasks.deploy-2.results.status)"
    - "$(tasks.deploy-3.results.status)"

3 parallel tasks, if one if them success, the 4th task will start to run.
but if one of the 3 task stuck, although another one already success, we still wait until timeout.

I means the requirements is: if any of the tasks success, do not wait others, the 4th should execute immediately. @jerop

@vincent-pli thanks for sharing your use case!

in that scenario, the 3 parallel tasks are all parent tasks to the 4th task (because it uses their results) so the 4th task won't be added to the execution queue until all its parent tasks are done

is it possible to share what the forth task is doing? i'm thinking that it could be best suited for a finally task, especially given that:

@jerop
Copy link
Member

jerop commented Jan 21, 2021

@bitsofinfo @vincent-pli check out the newly-added common expression language custom task which may be helpful for your use cases

@tekton-robot
Copy link
Collaborator

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale with a justification.
Stale issues rot after an additional 30d of inactivity and eventually close.
If this issue is safe to close now please do so with /close with a justification.
If this issue should be exempted, mark the issue as frozen with /lifecycle frozen with a justification.

/lifecycle stale

Send feedback to tektoncd/plumbing.

@tekton-robot tekton-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Apr 21, 2021
@bitsofinfo
Copy link
Author

/remove-lifecycle stale

@tekton-robot tekton-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Apr 22, 2021
@tekton-robot
Copy link
Collaborator

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale with a justification.
Stale issues rot after an additional 30d of inactivity and eventually close.
If this issue is safe to close now please do so with /close with a justification.
If this issue should be exempted, mark the issue as frozen with /lifecycle frozen with a justification.

/lifecycle stale

Send feedback to tektoncd/plumbing.

@tekton-robot tekton-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Oct 14, 2021
@jerop
Copy link
Member

jerop commented Nov 9, 2021

adding a reference to a slack thread where a user made a request for "OR" logic support in when expressions

https://tektoncd.slack.com/archives/CJ62C1555/p1636362405078900

/lifecycle frozen

@tekton-robot tekton-robot added lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Nov 9, 2021
@durera
Copy link

durera commented Mar 21, 2022

I have a pipeline whereby we have logic a little like this, and arrived here looking for exactly the same thing in the hope such support was now available, or in the pipeline:

  • install dependency1 if (param1) or (param2)
  • install app1 if (param1)
  • install app2 if (param2)

Basically we have two inputs, those inputs each directly control whether a certain branch in the pipeline is actived, but earlier in the pipeline there are some pre-req steps that are needed only if one or more of those optional branches are traversed. We can't use the status of the app1/app2 install steps as this step happens before they do.

The hacky workaround we put in place at the moment is this, which works as we use empty string in the parameter to indicate "don't install that application":

      when:
        - input: "$(params.param1)$(params.param2)"
          operator: notin
          values: [""]

We did want to do more complex logic based on content of the param (which carries a version number), but I don't see how we can do that without the kind of ANY match support discussed in this issue.

Example: One app only needs this step depending on the version chosen, the other needs it as long as it's installed (any version)

      whenAny:
        - input: "$(params.param1)"
          operator: notin
          values: [""]
        - input: "$(params.param2)"
          operator: in
          values: ["8.5", "8.6"]

@Yongxuanzhang
Copy link
Member

Hi, the CEL in WhenExpression has been supported in release v0.53 , which can be used to address the use case. Please try out the feature and if you have any suggestions, feel free to comment on this issue: #7358

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature. lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness.
Projects
Status: Todo
Development

No branches or pull requests

7 participants