Strange boolean evaluation rules

I’m trying to understand boolean expressions in GitHub actions. The documentation gives the following example of literals of different types, including boolean as ${{ false }} and ${{ true }}.

Following their lead I use the following step with an env section that sets VARF to false and VART to true and then in the run key has some test output:

  - name: Var test
      VARF: ${{ false }}
      VART: ${{ true }}
    run: |
      echo "VART=${{ env.VARF }}"
      echo "VART=${{ env.VART }}"
      echo "VARF && VART=${{ env.VARF && env.VART }}"
      echo "VARF || VART=${{ env.VARF || env.VART }}"
      echo "!VARF=${{ ! env.VARF }}"
      echo "!!VART=${{ !! env.VART }}"

The output is as follows:

VARF && VART=true
VARF || VART=false

The plain output is as expected, showing true and false. The output of the && and || operators is the opposite of expected, giving false && true == true and false || true == false. The output of ${{ ! env.VARF }} is false when I’d expect true.

What’s going on here? Possibly variables in the env context get coerced to strings, but that still doesn’t explain all the results.

env defines strings.

Consider this (node):

% node
Welcome to Node.js v16.7.0.
Type ".help" for more information.
> "false" && "true"
> "false" || "true"
> !"false"
> !"true"
> !!"true"

To do what you’re trying to do, you’d probably want something like:

      echo "VARF && VART=${{ fromJSON(env.VARF) && fromJSON(env.VART) }}"
1 Like

Technically env is defined here:
And use is covered here:

Practically, while it says they’re environment variables, it doesn’t actually say they’re strings, it just kinda assumes you’d figure that out.

If it were my project, I wouldn’t object to someone filing a bug/PR asking for the term string to be sprinkled around the various bits.

(It isn’t my project.)

1 Like