Someone knows if it is possible to use OR operator in needs
statement? let's say we expect a successful job-a OR job-b to run job-c, i.e.
name: My workflow
on:
workflow_dispatch:
jobs:
job-a:
runs-on: ubuntu-latest
steps:
- name: do something
run: echo "something"
job-b:
runs-on: ubuntu-latest
steps:
- name: do something
run: echo "something"
job-c:
runs-on: ubuntu-latest
needs:
- job-a OR job-b
steps:
- name: do something
run: echo "something"
if conditional to prevent a job from running unless a condition is met. You can use any supported context and expression to create a conditional. When you use expressions in an if conditional, you may omit the expression syntax ( ${{ }} ) because GitHub automatically evaluates the if conditional as an expression.
To set a custom environment variable, you must define it in the workflow file. The scope of a custom environment variable is limited to the element in which it is defined. You can define environment variables that are scoped for: The entire workflow, by using env at the top level of the workflow file.
github.head_ref. string. The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target . github.job.
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.
Yes it's possible. Unfortunately I have some cases where it doesn't always works as expected. But the idea is to do something as follow:
jobs:
job-a:
name: Job A
runs-on: ubuntu-latest
steps:
- run: true
job-b:
name: Job B
runs-on: ubuntu-latest
if: false
steps:
- run: true
job-ab:
name: Job AB
runs-on: ubuntu-latest
needs: [ job-a, job-b ]
if: ${{ always() && contains(needs.*.result, 'success') && !(contains(needs.*.result, 'failure')) }}
steps:
- run: true
By default when using needs
, any job in the dependency list that is skipped will trigger a skip of the current job. If you want to force the job to run you have to use the always()
function which will tell your job to always run. Unfortunately this means that it will run event if a job fails or if all the previous jobs are skipped. contains(needs.*.result, 'success')
will be true if at least one of the jobs succeeded. So if all your jobs are skipped it will be false. !(contains(needs.*.result, 'failure'))
is false if any job failed
I am a more detailed demo here.
You can combine jobs.<job_id>.outputs, jobs.<job_id>.steps[*].if, and jobs.<job_id>.needs:
jobs:
job1:
runs-on: ubuntu-latest
outputs:
output1: ${{ steps.step1.outputs.test }}
steps:
- id: step0
run: echo "something"
- id: step1
if: success()
run: echo "::set-output name=test::success"
job2:
runs-on: ubuntu-latest
outputs:
output2: ${{ steps.step1.outputs.test }}
steps:
- id: step0
run: echo "something"
- id: step1
if: success()
run: echo "::set-output name=test::success"
job3:
runs-on: ubuntu-latest
needs: [job1, job2]
if: needs.job1.outputs.output1 == 'success' && needs.job2.outputs.output2 == 'success'
steps:
- run: echo ${{needs.job1.outputs.output1}} ${{needs.job2.outputs.output2}}
Basically, on each job, your last step will set an output only if the other steps succeeded.
And then you can access those outputs through any job and do anything you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With