Anakhand
Anakhand

Reputation: 3028

Reference the runner context in job's env clause

Here's a GitHub Actions workflow file for a Python project named spam:

name: PyInstaller

on:
  [...]

jobs:
  create_release:
    [...]

  make_artifact:
    needs: create_release

    strategy:
      matrix:
        os: [ ubuntu-latest, windows-latest ]

    runs-on: ${{ matrix.os }}

    env:
      ARTIFACT_PATH: dist/spam.zip
      ARTIFACT_NAME: spam-${{ runner.os }}.zip
    
    steps:
      [...]

When this runs, the workflow fails at startup with this:

The workflow is not valid. [...]: 
Unrecognized named-value: 'runner'. Located at position 1 within expression: runner.os

I'm attempting to use the os attribute of the runner context. This SO Q&A mentions that the env context can only be used in specific places, so I suspect something similar is happening here. However, I can't find any official documentation addressing this.

Is there any way to reference the runner context to set an environment variable within the env clause of a job, as shown above?

I'm looking for a way to set the environment variable for all steps in the job, so an env inside a step item won't do. The workaround I've got for now is to add a step specifically to set environment variables:

steps:
  - name: Setup environment
    run: |
      echo "ARTIFACT_NAME=spam-${{ runner.os }}.zip" >> $GITHUB_ENV

however this only works on the Linux runner.

Upvotes: 3

Views: 1819

Answers (1)

jidicula
jidicula

Reputation: 3989

If you scroll down a bit further in the GitHub Actions docs you linked, there's an example workflow printing different contexts to the log.

- name: Dump runner context
        env:
          RUNNER_CONTEXT: ${{ toJson(runner) }}

I set up a test repo with a workflow demonstration:

on: push

jobs:
  one:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - 'ubuntu-latest'
          - 'windows-latest'
          - 'macos-latest'
    steps:
      - name: Dump runner context
        env:
          RUNNER_CONTEXT: ${{ toJson(runner) }}
        run: echo "$RUNNER_CONTEXT"
      - name: Get runner OS
        env:
          RUNNER_OS: ${{ runner.os }}
        run: echo "$RUNNER_OS"
      - name: Create file with runner OS in name
        env:
          OS_FILENAME: 'spam-${{ runner.os }}.zip'
        run: |
          echo "OS_FILENAME=spam-${{ runner.os }}.zip" >> $GITHUB_ENV
          touch "./${{ env.OS_FILENAME }}"
          touch blah.txt
      - name: List created file
        run: ls -l "./${{ env.OS_FILENAME }}"

It looks like you can also set and access env in steps, and those persist across workflow steps. For example, I set the environment variable $OS_FILENAME in step 3 using the echo syntax, and reference it in step 4. This works across all the OS options offered on GitHub Actions.

Note that the GitHub Actions docs state that "Environment variables must be explicitly referenced using the env context in expression syntax or through use of the $GITHUB_ENV file directly; environment variables are not implicitly available in shell commands.". Basically, it means you can't implicitly refer to env variables like $FOO and instead must refer to them as ${{ env.FOO }} in shell commands.

So for your scenario, does it satisfy your requirements if you set $ARTIFACT_NAME in the first step of the job? I wonder if the reason might be that the runner context isn't created until the first step - I'm not sure I have a way of testing this.

Upvotes: 4

Related Questions