Home > Enterprise >  Github actions "always()" condition not working as expected?
Github actions "always()" condition not working as expected?

Time:12-14

I am interested in why this always() condition is not behaving as expected in a Github workflow.

I have a core pipeline, which works just fine. If the secondary workflow fails, the tertiary still runs but only if boolean output from secondary workflow == true.

Within the secondary pipeline, the output step is supposed to run only if a boolean input is set to true. Although I have used the exact same syntax, it only seems to run if the condition is always() rather than always() &&.

This is the core pipeline (which works):

name: Core Pipeline
on: 
  workflow_dispatch:
    inputs: 
      boolean: 
        description: 'boolean'
        required: false
        default: true
        type: boolean 

jobs:
  secondary-workflow:
    uses: ./.github/workflows/secondary-workflow.yaml
    with:
      boolean: true 
  tertiary-workflow:
    needs: secondary-workflow
    uses: ./.github/workflows/tertiary-workflow.yaml
    if: always() && needs.secondary-workflow.outputs.boolean == 'true'

This is secondary-workflow (doesn't work as intended):

on: 
  workflow_call:
    inputs: 
      boolean: 
        description: 'Boolean'
        required: false
        default: true
        type: boolean 
    outputs: 
      boolean: 
        description: "Test Output"
        value: ${{ jobs.job-4.outputs.boolean }}

jobs:
  job-1:
    runs-on: ubuntu-latest
    steps:
      - name: job 1 
        run: echo 'This job runs'
  job-2:
    runs-on: ubuntu-latest
    needs: job-1
    steps:
      - name: job 2
        run: echo 'This job runs'
  job-3:
    runs-on: ubuntu-latest
    needs: [job-1, job-2]
    steps:
      - name: Exit 
        run: echo "This job fails"; exit 1 
  job-4:
    runs-on: ubuntu-latest
    needs: [job-1, job-2, job-3]
    if: always() && inputs.boolean == 'true' (ADDING THE && CAUSES THE JOB TO BE SKIPPED) 
    steps:
      - id: setOutput
        run: echo "boolean=true" >> $GITHUB_OUTPUT; echo "OUTPUT_SET"
    outputs:
      boolean: ${{ steps.setOutput.outputs.boolean }}

My question is, why does adding a second condition in addition to always() work for the core pipeline but not for the secondary pipeline?

Thanks!

CodePudding user response:

When you compare

if: always() && inputs.boolean == 'true'

you're comparing a boolean to a string. On type mismatch, actions coerce the operands to numbers; true becomes 1, and 'true' (the string) becomes NaN, and 1 == NaN is false. To fix, you can compare to a boolean literal instead of a string:

if: always() && inputs.boolean == true

or you should be able to just check the boolean on its own:

if: always() && inputs.boolean

As for why the seemingly identical condition works in one place and not in the other, my guess is that the input parameter in the reusable workflow is typed as a boolean, whereas needs.secondary-workflow.outputs.boolean is a string, so comparison to 'true' works.

  • Related