if conditional evaluated wrong for contains(needs.*.result, 'failure')
See original GitHub issueDescribe the bug A job-level if conditional isn’t evaluated properly when using the contains function and array wildcard syntax.
For example, if contains(needs.*.result, 'failure')
evaluates to false, a job with if: always() && contains(needs.*.result, 'failure')
will run, but a job with if: always() && (needs.job_a.result == 'failure' || needs.job_b.result == 'failure')
won’t run.
To Reproduce
- Run a workflow with the following yaml configuration. Examining the output reveals that:
a. Job a fails
b. Job b is skipped
c. Job c is skipped
d. Job d runs (unexpected) even though
contains(needs.*.result, 'failure')
evaluates to false
jobs:
a:
runs-on: ubuntu-latest
steps:
- run: |
echo "This job fails."
exit 1
b:
runs-on: ubuntu-latest
if: ${{ false }}
needs: a
steps:
- run: echo "This job never happens."
c:
runs-on: ubuntu-latest
if: ${{ false }}
needs: [a, b]
steps:
- run: echo "This job never happens."
d:
runs-on: ubuntu-latest
needs: [b, c]
if: always() && contains(needs.*.result, 'failure')
steps:
- run: |
echo "I don't want this to run unless b or c fails!"
echo ${{ contains(needs.*.result, 'failure') }} # Evaluates to false!
- However, running a workflow with the following yaml has the expected outcome: a. Job a fails b. Job b is skipped c. Job c is skipped d. Job d is skipped (expected)
jobs:
a:
runs-on: ubuntu-latest
steps:
- run: |
echo "This job fails."
exit 1
b:
runs-on: ubuntu-latest
if: ${{ false }}
needs: a
steps:
- run: echo "This job never happens."
c:
runs-on: ubuntu-latest
if: ${{ false }}
needs: [a, b]
steps:
- run: echo "This job never happens."
d:
runs-on: ubuntu-latest
needs: [b, c]
if: always() && (needs.b.result == 'failure' || needs.c.result == 'failure') # ONLY CHANGE
steps:
- run: |
echo "I don't want this to run unless b or c fails!"
echo ${{ contains(needs.*.result, 'failure') }} # Evaluates to false!
Expected behavior
if: always() && contains(needs.*.result, 'failure')
should have the same behavior as if: always() && (needs.b.result == 'failure' || needs.c.result == 'failure')
. In other words, if: always() && contains(needs.*.result, 'failure')
should evaluate to false and job d should be skipped.
Runner Version and Platform
Version of your runner? Not sure - running with GitHub Actions (not self-hosted runner)
OS of the machine running the runner? ubuntu-latest
Issue Analytics
- State:
- Created 2 years ago
- Reactions:9
- Comments:7 (1 by maintainers)
Top GitHub Comments
Just hopping on to hopefully encourage some movement on this issue; I spent way too long debugging my workflow before finding the solution in this thread.
Hi there, not related to the original issue, but could this inconsistency with respect to indirect dependencies please be fixed? The same condition could pass at the job level but not at the step level, this is error prone: I spent some time debugging a workflow because of that. Thanks!