Reputation: 8801
Below is my GitHub workflow
name: APP Build
on:
push:
branches:
- feature/test
jobs:
test-1:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test1') }}
steps:
- name: test-fail
run: echo "test1"
test-2:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test2') }}
steps:
- name: test-fail
run: echo "test1"
notify-slack:
name: Slack Notification
runs-on: ubuntu-latest
needs: [test-1, test-2]
steps:
- name: Slack Notification
uses: rtCamp/[email protected]
env:
SLACK_CHANNEL: alert
SLACK_COLOR: "${{ job.status == 'success' && 'good' || 'danger' }}"
Question: test1
and test2
job is conditional as per my commit message but notify slack need either test1
or test2
. I can't put both because if either the job skip notify-slack
will skip as well. How to make this work?
Upvotes: 20
Views: 18579
Reputation: 2239
I've just bumped into this issue myself and I didn't like the solutions here as it requires if: always()...
to be added to EVERY job after the conditional one, making it hard to maintain.
I noticed that workflow status was success
even if only the first job executed and everything else was skipped, so I decided to try to move the conditional part to a separate workflow and call it as a re-usable workflow.
In my case, I had 2 conditionally exclusive jobs, so one of them always executed, not exactly the same as your test-1
and test-2
(where both can be skipped).
name: test helper
on:
workflow_call:
jobs:
test-1:
runs-on: ubuntu-latest
steps:
- run: |
echo h1
if: ${{ true }}
test-2:
runs-on: ubuntu-latest
steps:
- run: |
echo bc
if: ${{ false }}
Then the main workflow
jobs:
tests:
uses: ./.github/workflows/helper.yaml
notify-slack:
name: Slack Notification
runs-on: ubuntu-latest
needs: tests
I found this a cleaner approach. If workflow fails, it will be failure. If the jobs are skipped or successful, workflow is successful.
I think only scenario that needs tweaking is if you need notify-slack to be skipped if both steps are skipped.
Not sure about the best way for that, but using workflow output (combining outcomes) could work.
Upvotes: 0
Reputation: 40603
There is an issue on Github about this. You need to add condition like below:
test-1:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test1') }}
steps:
- name: test-fail
run: echo "test1"
test-2:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test2') }}
steps:
- name: test-fail
run: echo "test1"
notify-slack:
name: Slack Notification
runs-on: ubuntu-latest
needs: [test-1, test-2]
if: |
always() &&
(needs.test-1.result == 'success' || needs.test-1.result == 'skipped') &&
(needs.test-2.result == 'success' || needs.test-2.result == 'skipped') &&
!(needs.test-1.result == 'skipped' && needs.test-2.result == 'skipped')
steps:
- name: Slack Notification
uses: rtCamp/[email protected]
env:
SLACK_CHANNEL: alert
SLACK_COLOR: "${{ job.status == 'success' && 'good' || 'danger' }}"
Upvotes: 23
Reputation: 3538
Implementation such condition can be achieved by using following workflow logic
jobs:
A:
runs-on: ubuntu-latest
steps:
- run: echo "success always"
B:
runs-on: ubuntu-latest
if: false
steps:
- run: echo "this will never run"
C:
runs-on: ubuntu-latest
steps:
- run: |
exho "here to fail"
exit 1
D:
runs-on: ubuntu-latest
needs: [A, B, C]
if: |
always() &&
!contains(needs.*.result, 'cancelled')
# you can add conditions if needed e.g.
# !contains(needs.*.result, 'failure')
steps:
- run: echo "${{ toJSON(needs) }}"
Your need to modify also your SLACK_COLOR
logic. job.status == 'success'
will not work since it will always be success
for this job regardless did any of the dependencies failed. Use needs
for your logic e.g. job D
output is:
{
A: {
result: success,
outputs: {}
},
B: {
result: skipped,
outputs: {}
},
C: {
result: failure,
outputs: {}
}
}
so you SLACK_COLOR
could be set like this
SLACK_COLOR: "${{ contains(needs.*.result, 'failure') && 'danger' || 'good' }}"
Upvotes: 7