Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boolean inputs are not actually booleans #1483

Closed
MetRonnie opened this issue Nov 12, 2021 · 57 comments
Closed

Boolean inputs are not actually booleans #1483

MetRonnie opened this issue Nov 12, 2021 · 57 comments
Assignees
Labels
Service Bug Bug fix scope to the pipelines service and launch app

Comments

@MetRonnie
Copy link

MetRonnie commented Nov 12, 2021

Describe the bug

Boolean type inputs do not work as expected; they are strings instead of booleans, even when surrounded by ${{ }} (e.g. in a step's if condition).

To Reproduce
Steps to reproduce the behavior:

Run this workflow using the workflow dispatch, with the foo input checkbox not ticked:

name: Thingy

on:
  workflow_dispatch:
    inputs:
      foo:
        description: Whether to foo
        type: boolean
        required: false
        default: false

jobs:
  thingy:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    env:
      FOO: ${{ github.event.inputs.foo }}
    steps:
      - name: Check value
        run: |
          echo "The value is: $FOO"

      - name: Run if foo
        if: ${{ github.event.inputs.foo }}
        run: |
          echo "Foo!"

      - name: Don't run if foo  # Eh, I meant "Run if not foo"
        if: ${{ ! github.event.inputs.foo }}
        run: |
          echo "Foo!"

Expected behavior

When the input is false, the Run if foo step should be skipped , and the Don't run if foo step should run.

Runner Version and Platform

Version of your runner? 2.284.0

OS of the machine running the runner? ubuntu-latest (20.04.3)

What's not working?

The value of github.event.inputs.foo is false, yet the Run if foo step runs and the Don't run if foo step is skipped.

image

Additional context

It is the same for a string input type or boolean input type (https://github.blog/changelog/2021-11-10-github-actions-input-types-for-manual-workflows/).

Only if: ${{ github.event.inputs.foo == 'true' }} works. So the input must be being treated as a string.

This goes against what the documentation says at https://docs.github.com/en/actions/learn-github-actions/expressions#about-expressions:

...evaluate an expression rather than treat it as a string.

${{ <expression> }}

@MetRonnie MetRonnie added the bug Something isn't working label Nov 12, 2021
MetRonnie added a commit to MetRonnie/cylc-doc that referenced this issue Nov 12, 2021
- Nightly build timing out
- `if` condition in deploy workflow doesn't work as expected - actions/runner#1483
@ChristopherHX
Copy link
Contributor

I guess this is a github service bug, sadly broken by design :(.

the value of the workflow_dispatch payload is 'false', but both of us are expecting a boolean false and not a string.
Why does this happen? 'false' is a non empty string, which is truthy.

${{ github.event.inputs.foo }}
${{ 'false' }}
${{ true }}

However this might align to previous workflow_dispatch behavior, all inputs are strings like before.

This is super inconsistent with reusable workflows workflow_call ( beta ), because type: boolean does mean boolean and not a string like in workflow_dispatch.

name: called
on:
  workflow_call:
    inputs:
      x:
        type: boolean

jobs:
  test1:
    runs-on: ubuntu-latest
    steps:
    - run: echo '${{inputs.x}}'
      if: ${{inputs.x}}
name: caller
on:
  push:
jobs:
  test2:
    uses: <owner>/<repo>/.github/workflows/called.yml@<ref>
    with:
      x: false

image

@MetRonnie MetRonnie changed the title Boolean inputs do not work in if: Boolean inputs are not actually booleans Dec 2, 2021
@solarmosaic-kflorence
Copy link

I have run into this issue as well, it is tricky to identify and debug. I have just been ensuring I always cast potential boolean values to a string, and always match on the string value.

@TingluoHuang
Copy link
Member

@ericsciple do you have any thoughts on this?

@piotrekkr
Copy link

Seems like input field type in workflow is only for GitHub to know what UI controls should it use and all inputs are strings... So it seems we should check it like if: ${{ inputs.x == 'true' }}

@solarmosaic-kflorence
Copy link

@piotrekkr it is the same for outputs, for example:

outputs:
  foo:
    description: "Returns true or false"
    value: ${{ steps.foo.outputs.bar == 'true' }}

The foo output would be type boolean, like false, but matching on outputs.foo == false doesn't seem to work. So instead I do:

outputs:
  foo:
    description: "Returns true or false"
    value: "${{ steps.foo.outputs.bar == 'true' }}"

And then match on outputs.foo == 'true' instead, which works every time.

@piotrekkr
Copy link

@solarmosaic-kflorence Yeah they should clearly document this behavior it can be really confusing. Maybe there is some documentation mentioning this but I did not stumbled upon this for a year now when working with GitHub...

@scottmmjackson
Copy link

This is actually really bad because there's no way to write a workflow such that if this bug is fixed your workflow continues to operate as normal. I can't figure out an expression that returns true only if a variable is not the string 'false' and also not the boolean false, because any boolean test I do will be coercing the argument and returning true absent a literal empty string argument.

@ChristopherHX
Copy link
Contributor

I can't figure out an expression that returns true only if a variable is not the string 'false' and also not the boolean false

Have you tried ${{fromJSON(github.event.inputs.foo)}} or ${{fromJSON(github.event.inputs.foo)}}? I'm not shure if this 100% does what you expect..
The trick fromJSON expects a string value, if it receives a boolean it is converted to string false => 'false', true => 'true'. Then fromJSON translates the boolean string back to a real boolean.

You can also cast the input to a string with ${{format('{0}', github.event.inputs.foo)}} then you always have the boolean as string. Then you could use ${{format('{0}', github.event.inputs.foo) != 'false'}}, this might even work with malformed inputs which aren't valid json.

@piotrekkr
Copy link

piotrekkr commented Dec 17, 2021

This is actually really bad because there's no way to write a workflow such that if this bug is fixed your workflow continues to operate as normal. I can't figure out an expression that returns true only if a variable is not the string 'false' and also not the boolean false, because any boolean test I do will be coercing the argument and returning true absent a literal empty string argument.

@scottmmjackson Seems like something like this could work I think (still seems quite ugly):

${{ github.event.inputs.foo && github.event.inputs.foo != 'false' }}

should give

true    && true    != 'false'   => true
'true'  && 'true'  != 'false'   => true
false   && false   != 'false'   => false
'false' && 'false' != 'false'   => false

//EDIT

Ok seems like it may not work with empty strings because javascript...

'' && '' != 'false' => ""

@kagahd
Copy link

kagahd commented Feb 7, 2022

I have a similar case by reusing workflows where I want let the caller of the reused workflow decide about continue-on-error

I found the following workaround, where the input variable type is string instead of boolean which is casted to boolean by fromJSON later on:

on:
  workflow_call:
    inputs:
      continue-on-error:
        type: string
        required: false
        default: false

jobs:
  my-job:
    name: 'my job'
    runs-on: ubuntu-latest
    env:
      CONTINUE_ON_ERROR: ${{inputs.continue-on-error}}
    steps:
      - uses: actions/checkout@v2
      - name: run foo
        shell: bash
        continue-on-error: ${{ fromJSON(env.CONTINUE_ON_ERROR) }}

@nikola-jokic nikola-jokic self-assigned this Feb 11, 2022
tevans-submittable added a commit to tevans-submittable/docs that referenced this issue Feb 11, 2022
Many people are confused by the usage of boolean.  actions/runner#1483

invalid
if: ${{ inputs.perform_deploy }}
if: inputs.perform_deploy

Must be treated as string
@mike-carey

This comment was marked as outdated.

zhongfly added a commit to zhongfly/mpv-winbuild that referenced this issue Feb 13, 2022
@kagahd
Copy link

kagahd commented Feb 15, 2022

I updated my comment above because the input variable type has to be string instead of boolean which is casted to boolean by fromJSON later on when the variable is being read and used.

cwrau added a commit to teutonet/teutonet-helm-charts that referenced this issue May 14, 2024
@Kristonitas
Copy link

This isn't happening any more since some time 2023: github/docs@e7a6d02

Inputs are still strings (when using gh workflow run, but the "boolean" input behaves like an enum with "true" and "false" being the only two options that are later cast to a proper boolean. I imagine numbers could be working same way, but didn't validate that.

I'm confused about the recent activity referencing this issue. Did the problem reappear at some point?
image

@chkp-sergeyl
Copy link

well, this is still not working as expected. putting if: ${{ inputs.SOME_BOOLEAN }} doesn't evaluate booleans.

@piotrekkr
Copy link

This isn't happening any more since some time 2023: github/docs@e7a6d02

Inputs are still strings (when using gh workflow run, but the "boolean" input behaves like an enum with "true" and "false" being the only two options that are later cast to a proper boolean. I imagine numbers could be working same way, but didn't validate that.

I'm confused about the recent activity referencing this issue. Did the problem reappear at some point? image

@Kristonitas I think those issues you added in screenshot were about output params and not inputs. Maybe outputs were mixed with inputs by some people and those were incorrectly linked to this issue.

@hassanalamibmx
Copy link

well, this is still not working as expected. putting if: ${{ inputs.SOME_BOOLEAN }} doesn't evaluate booleans.

It's working great for me, can you provide an example?

@Kristonitas
Copy link

@libermansa
I remade the test that was posted early in this issue, with results that we expect from bool inputs:
https://github.com/Kristonitas/ga-bool-input-test
image
image

The scenario that was reported in #1483 (comment) (and other similar tests) is not happening right now

@piotrekkr
Thanks for pointing that out

P. S. The arguments passed between workflows are still serialised as strings afaik (hence you can't use json booleans when using the json input flag echo '{"passed_true": true, "passed_false": false}' | gh workflow run test.yml --json would fail). So seeing strings as output "booleans" could still make sense.

@rainabba
Copy link

I found that I needed to use fromJSON() (see: https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson) around my "boolean" params to get them to behave as expected.

@sanjacob
Copy link

sanjacob commented Aug 14, 2024

Still happens in env at least. I had to use fromJSON

inputs:
  dev:
    description: "Also add development requirements"
    default: false
    type: boolean

steps:
    - env:
        ARG_DEV: ${{ fromJSON(inputs.dev) && '--dev' || '' }}
      run:  pipenv install $ARG_DEV
      shell: bash

grooverdan added a commit to grooverdan/mariadb-buildbot that referenced this issue Aug 22, 2024
To solve chicken/egg problem of providing galera
workers to build the galera-4 package.

nogalera defined as string due to
actions/runner#1483.

It defaults to true, so the few build images that
don't set it (mainly about to be EOL distros), or new
distros that accidently omit it won't fail.
grooverdan added a commit to grooverdan/mariadb-buildbot that referenced this issue Aug 22, 2024
To solve chicken/egg problem of providing galera
workers to build the galera-4 package.

nogalera defined as string due to
actions/runner#1483.

It defaults to true, so the few build images that
don't set it (mainly about to be EOL distros), or new
distros that accidently omit it won't fail.
RazvanLiviuVarzaru pushed a commit to MariaDB/buildbot that referenced this issue Aug 22, 2024
To solve chicken/egg problem of providing galera
workers to build the galera-4 package.

nogalera defined as string due to
actions/runner#1483.

It defaults to true, so the few build images that
don't set it (mainly about to be EOL distros), or new
distros that accidently omit it won't fail.
ShamrockLee added a commit to ShamrockLee/transcript-timestamper that referenced this issue Aug 22, 2024
matthewhartstonge added a commit to linc-technologies/.github that referenced this issue Oct 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Service Bug Bug fix scope to the pipelines service and launch app
Projects
None yet
Development

No branches or pull requests