runner: Unrecognized named-value: 'env'. for job conditional

Describe the bug

Use of env in job conditionals causes an invalid config. Cross posting this from nektos/act#720

Expected behaviour

GitHub Actions should not error regarding ${{ !env.ACT }}

Actual behaviour

GitHub Actions says workflow is not valid because of ${{ !env.ACT }}

The workflow is not valid. .github/workflows/deploy.yml (Line: 11, Col: 13): Unrecognized named-value: 'env'. Located at position 2 within expression: !env.ACT

Workflow and/or repository

Erroring Workflow

workflow
name: Deploy
on:
    push:
        branches:
            - release
    # run for every pull request
    pull_request: {}
jobs:
    deploy:
        name: Deploy
        if: ${{ !env.ACT }} # skip during local actions testing
        runs-on: ubuntu-latest
        strategy:
            matrix:
                node: [12]
        steps:
            - name: Checkout repo
              uses: actions/checkout@v2

            - name: Setup node
              uses: actions/setup-node@v1
              with:
                  node-version: ${{ matrix.node }}

            - name: 📥 Download deps
              uses: bahmutov/npm-install@v1
              with:
                  useLockFile: false

            - name: Deploy
              run: npx semantic-release@15

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 42
  • Comments: 16 (1 by maintainers)

Commits related to this issue

Most upvoted comments

Well I wasted a few dollars of minutes and a few hours of my day based on that sentence so whether or not everyone gets confused by it I can say with certainty I got confused and frustrated by it.

Whether or not anyone wants to fix it is beyond the scope of my authority but enough of these frustrations in the documentation and I’ll surely go back to circleci for my CI 😕

env is also not usable within a job which uses a shared workflow, within the with block e.g.:

env:
  MY_ENV: test
jobs:
  some-job:
    uses: Org/repo/path/to/workflow.yml@master
    with:
      some-input: ${{ env.MY_ENV }}

Would really like this functionality to be in place - I don’t understand how it’s possible to develop any sort of custom caching without this functionality. This would save us a tremendous amount of time and sanity.

I think it’s suppose to work but doesn’t. There is an an official example of using env in an if here: https://docs.github.com/en/actions/learn-github-actions/environment-variables#using-contexts-to-access-environment-variable-values

Following up to this: I still think the docs are wrong. They state:

For example, an if conditional, which determines whether a job or step is sent to the runner,

This seems to imply that an env variable could be used in a job and a step but that doesn’t seem to be the case.

Did anyone create that feature request? I appreciate the link to contexts docs because this behavior was not at all obvious to me from this documentation:

The env context syntax allows you to use the value of an environment variable in your workflow file. You can use the env context in the value of any key in a step except for the id and uses keys. For more information on the step syntax, see “Workflow syntax for GitHub Actions.”

So I guess they are using the term step to have some technically precise meaning, like a subkey of jobs.<job_id>.steps? Seems like the validator could give much better hints about the cause of the error here (e.g. “You attempted to used env, but env is not available in the context of … See this docs page for more details…”

I think it’s suppose to work but doesn’t. There is an an official example of using env in an if here:

No, in that case the if is part of a step, which works (see jobs.<job_id>.steps.if in table linked below). The problem is that it is counter-intuitive for a developer who may be in the habit of thinking about the YAML file as something like a “shell script” wherein environment variables are globally accessible. The things that can be accessed (context) in a given place (workflow key) are listed here: https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability I think it would be very helpful if attempted accesses to unavailable contexts caused a warning to be generated (and perhaps linked to that table).

env is also not usable within a job which uses a shared workflow, within the with block e.g.:

Well, to a poor soul that stumbles upon this issue, I have a solution (crutch-lution?) for the crutch-full github actions system.

The idea is to convert env: to outputs and they for whatever unholy reason 🔯 can be used in the with for workflow call.

With that idea in mind the abomination was created:


env:
  # Global vars
  YOUR_VAR_1: 'whatever value you want to pass'
  YOUR_VAR_2: rc.${{ github.sha }}-whatever

jobs:
  github_sucks:
    runs-on: ubuntu-latest
    outputs:
      YOUR_VAR_1: ${{ steps.blah.outputs.YOUR_VAR_1 }}
      YOUR_VAR_2: ${{ steps.blah.outputs.YOUR_VAR_2 }}
    steps:
      - id: blah
        run: |
          vars="
          YOUR_VAR_1
          YOUR_VAR_2
          "
          setOutput() {
            echo "${1}=${!1}" >> "${GITHUB_OUTPUT}"
          }
          for name in $vars; do
            setOutput $name
          done

  build:
    needs: [ <actual dependencies> , github_sucks ]
    uses: ./.github/workflows/build_action.yml
    secrets: inherit
    with:
      whatever_input_1: ${{ needs.github_sucks.outputs.YOUR_VAR_1 }}
      whatever_input_2: ${{ needs.github_sucks.outputs.YOUR_VAR_2 }}

The big downside, beside this being a very big crutch, is that you have to hardcode the variable names in the converter job. I did not found a sane way to even get the list of env keys, you could use ${{ toJSON(env) }} and parse it in the run via jq or something similar but it would be adding more salt to the wound.

I just got bit by this, not with env, but with vars. And yes, it appears to be an odd edgecase of failed support in reusable workflows around passing inputs to actions. We have an organization level variable of NODE_VERSION that we cannot use in any of our workflows. It produces the error Unrecognized named-value: 'vars'. Located at position 1 within expression: vars.NODE_VERSION

env is also not usable within a job which uses a shared workflow, within the with block e.g.:

Oh what the…why github actions have to be so much worse and immature compared to the gitlab.

Now I have to rewrite everything again, great idea of using env: for global constants goes to the dumpster.

Also got this error when trying to define job-level env-vars in terms of other job-level env-vars:

  acme-bundle:
    runs-on: ubuntu-20.04
    needs: build
    env:
      # if triggered from a branch containing /, use "wip", otherwise tag name
      version: ${{ contains(github.ref_name, '/') && 'wip' || github.ref_name }}
      fullfilename: acme-${{ env.version }}.${{ github.sha }}.bundle
    steps:
      ...
      - name: Pack
        run: tar -czf $fullfilename --format posix -C DIST .
      - name: Upload
        run: aws s3 cp $fullfilename s3://$BUCKET/ACME/$version/$fullfilename

— by GH Actions rules, the definition of env.fullfilename is forbidden to use env.version on the previous line 🤦‍♂️

The workflow is not valid. .github/workflows/release.yml (Line: 190, Col: 21): Unrecognized named-value: ‘env’. Located at position 1 within expression: env.version


Instead of trying to untangle the truckload of flavors of “a variable” 🙄 from GH Actions docs (vars definable on 5 nesting levels, env vars with 3 nesting levels, contexts… oh my!) — just use the shell.

Shell variables (and “actions” BTW too) are simple enough:

  acme-bundle:
    runs-on: ubuntu-20.04
    needs: build
    # NOTE the job-level `env` yaml is useless https://github.com/actions/runner/issues/1189
    steps:
      - name: Format acme-bundle filename
        run: |
          # if triggered from a branch containing /, use "wip", otherwise tag name
          version="${{ contains(github.ref_name, '/') && 'wip' || github.ref_name }}"
          fullfilename="acme-${version}.${GITHUB_SHA}.bundle"
          { echo "version=$version"
            echo "fullfilename=$fullfilename"
          } >> $GITHUB_ENV
      ...
      - name: Pack
        run: tar -czf $fullfilename --format posix -C DIST .
      - name: Upload
        run: aws s3 cp $fullfilename s3://$BUCKET/ACME/$version/$fullfilename