Reputation: 1888
I have a workflow that executes a bunch of fuzz tests and, at the end, calculates the total number of files in all crashers
sub-directories. Later, in another job, I use that number to send a notification to Slack. But, for some reason, ::set-output
produces no output and, most importantly, the next job does not get run even though the number of crashers
is not zero!
jobs:
fuzz-nightly-test:
runs-on: ubuntu-latest
steps:
...
- name: Set crashers count
working-directory: test/fuzz
run: echo "::set-output name=crashers-count::$(find . -type d -name 'crashers' | xargs -I % sh -c 'ls % | wc -l' | awk '{total += $1} END {print total}')"
id: set-crashers-count
outputs:
crashers-count: ${{ steps.set-crashers-count.outputs.crashers-count }}
fuzz-nightly-fail:
needs: fuzz-nightly-test
if: ${{ needs.set-crashers-count.outputs.crashers-count != 0 }}
runs-on: ubuntu-latest
steps:
...
Does anybody know what I am doing wrong? Thank you!
Upvotes: 6
Views: 11292
Reputation: 3929
I did a bunch of tests with a similar minimal example and I think I figured out the issue. Most immediately, in your if
directive in your fuzz-nightly-fail
job, you need to be accessing needs.<job_id>.outputs.<job_output_id>
rather than needs.<step_id>.outputs.<job_output_id>
. Therefore, the if
directive would become if: ${{ needs.fuzz-nightly-test.outputs.crashers-count != 0 }}
.
Additionally, you should probably make a step output ID that's distinct from the job output ID to save yourself from some confusion about what context object is being referenced where. So, the run
statement in your first job could be something like run: echo "::set-output name=count::$(find . -type d -name 'crashers' | xargs -I % sh -c 'ls % | wc -l' | awk '{total += $1} END {print total}')"
and the job output would also be changed to crashers-count: ${{ steps.set-crashers-count.outputs.count }}
. Putting this all together, we get
jobs:
fuzz-nightly-test:
runs-on: ubuntu-latest
steps:
...
- name: Set crashers count
working-directory: test/fuzz
run: echo "::set-output name=count::$(find . -type d -name 'crashers' | xargs -I % sh -c 'ls % | wc -l' | awk '{total += $1} END {print total}')"
id: set-crashers-count
outputs:
crashers-count: ${{ steps.set-crashers-count.outputs.count }}
fuzz-nightly-fail:
needs: fuzz-nightly-test
if: ${{ needs.fuzz-nightly-test.outputs.crashers-count != 0 }}
runs-on: ubuntu-latest
steps:
...
The reason for this isn't immediately obvious from the documentation alone, but the example here implies that <step_id>.outputs.foo
is different from <job_id>.outputs.foo
- jobs.job1.outputs.output1
is defined as that job's steps.step1.outputs.test
.
You can see a (very) minimal example of this here, with its corresponding workflow run here.
Upvotes: 16