18

I've been trying to build a CICD pipeline in Github actions and we're not able to process if and or conditions in the same. below is the example of our code snippet,

    name: Build Non prod
    needs: [rules]    
    if: ${{ (needs.rules.outputs.branch_name != 'production') || (needs.rules.outputs.branch_name != 'staging') }}
    steps:
      - name: Checkout
        uses: actions/checkout@v2

So this task should not run in production and staging branch, but when actions runs in staging branch, this job is also getting triggered along with other jobs which are not meant for staging environment.

Is there any way we can have if and or condition ?

Update:

The condition will not work, below updated condition will work.

if: ${{ (needs.rules.outputs.branch_name != 'production') && (needs.rules.outputs.branch_name != 'staging') }}
Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
Sam-Sundar
  • 511
  • 1
  • 4
  • 12
  • Could you share your `rules` stage/job? – Krzysztof Madej Jul 10 '21 at 12:12
  • Hey, the issue is solved. Had to use below condition for it to not run on staging and production environment. So when it's in Development or QA env, it's satisfying below condition and the job is skipped . ```yaml if: ${{ (needs.rules.outputs.branch_name != 'production') && (needs.rules.outputs.branch_name != 'staging') }} ``` And when it's in Staging or Production environment below code snippet will tell actions to run and not skip ```yaml if: ${{ (needs.rules.outputs.branch_name != 'production') ||(needs.rules.outputs.branch_name != 'staging') }} ``` – Sam-Sundar Jul 12 '21 at 05:09
  • not a OR not b will always evaluate to true, as a != b. if you want them both excluded, change your logic to AND like in your comment & the suggested answer – Sandra May 06 '22 at 12:47

1 Answers1

17

You condition should look like below:

   name: Build Non prod
    needs: [rules]    
    if: ${{ (needs.rules.outputs.branch_name != 'production') && (needs.rules.outputs.branch_name != 'staging') }}
    steps:
      - name: Checkout
        uses: actions/checkout@v2

However if you find it not working it could be related to this issue - Job-level "if" condition not evaluated correctly if job in "needs" property is skipped

Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
  • Hey, I tried this too, and it also seems to be not working. If the `if` is not getting validated, it's still running the job. – Sam-Sundar Jul 09 '21 at 13:39
  • 5
    Krzysztof: According to [this section](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idif), `If the expression contains any operators, the expression must be contained within ${{ }} to explicitly mark it for evaluation`. So you would need to use `${{ }}` anyway in this case. – GuiFalourd Jul 09 '21 at 18:24
  • Sam: Did you try using `always() &&` at the beginning of the expression? According to [this post](https://github.com/actions/runner/issues/491#issuecomment-850884422) it might resolve the problem. – GuiFalourd Jul 09 '21 at 18:34
  • 3
    Hey @GuiFalourd & @Krzysztof The issue is solved. Had to use below condition for it to not run on staging and production environment. So when it's in Development or QA env, it's satisfying below condition and the job is skipped . ```yaml if: ${{ (needs.rules.outputs.branch_name != 'production') && (needs.rules.outputs.branch_name != 'staging') }} ``` And when it's in Staging or Production environment below code snippet will tell actions to run and not skip ```yaml if: ${{ (needs.rules.outputs.branch_name != 'production') ||(needs.rules.outputs.branch_name != 'staging') }} ``` – Sam-Sundar Jul 12 '21 at 05:13
  • @Sam-Sundar I updated my reply with valid condition. Feel free to accept it as answer to do not disturb other user as this case is solved or please publish your own reply. – Krzysztof Madej Jul 12 '21 at 06:57
  • in my case, I needed to put my `env` vars on the same level as the `steps` in my yaml, as otherwise the `if` _inside_ a step didn't have access to those variables. – Sandra May 06 '22 at 12:48
  • @Sam-Sundar `if: ${{ (needs.rules.outputs.branch_name != 'production') ||(needs.rules.outputs.branch_name != 'staging') }} ` - if production, this will evaluate to true, because it's not staging. if staging, it'll also evaluate to true, as it's not production. using the combination`!=` ... `||` ...`!=` will make your logic **always** evaluate to true (regardless of the branch name) – Sandra May 06 '22 at 12:55