Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GitHub-actions OR operator for needs clause

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"

like image 310
Jesus Vidal Avatar asked Feb 24 '21 00:02

Jesus Vidal


People also ask

How do I use conditions in GitHub Actions?

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.

How do I set environment variables in GitHub Actions?

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.

What is GitHub Head_ref?

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.

What can GitHub Actions be used for?

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.


2 Answers

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.

like image 131
ITChap Avatar answered Oct 22 '22 05:10

ITChap


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.

like image 26
soltex Avatar answered Oct 22 '22 05:10

soltex