226

In GitHub Actions, I'd like to evaluate a bash expression and then assign it to an environment variable:

    - name: Tag image
      env:
        GITHUB_SHA_SHORT: ${{ $(echo $GITHUB_SHA | cut -c 1-6) }}
      ..do other things...

However, this naive attempt has failed. According to the docs this doesn't seem to be supported; a somewhat clean workaround would be fine.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
evilSnobu
  • 24,582
  • 8
  • 41
  • 71
  • 1
    Maybe `set-env` would work in a previous step. https://help.github.com/en/articles/development-tools-for-github-actions#set-an-environment-variable-set-env – peterevans Sep 17 '19 at 07:23

3 Answers3

369

The original answer to this question used the Actions runner function set-env. Due to a security vulnerability set-env is being deprecated and should no longer be used.

This is the new way to set environment variables.

name: my workflow
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Set env
      run: echo "GITHUB_SHA_SHORT=$(echo $GITHUB_SHA | cut -c 1-6)" >> $GITHUB_ENV
    - name: Test
      run: echo $GITHUB_SHA_SHORT

Setting an environment variable echo "{name}={value}" >> $GITHUB_ENV

Creates or updates an environment variable for any actions running next in a job. The action that creates or updates the environment variable does not have access to the new value, but all subsequent actions in a job will have access. Environment variables are case-sensitive and you can include punctuation.

(From https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable)

Example using the output to $GITHUB_ENV method:

    echo "GITHUB_SHA_SHORT=$(echo $GITHUB_SHA | cut -c 1-6)" >> $GITHUB_ENV

This is an alternative way to reference the environment variable in workflows.

    - name: Test
      run: echo ${{ env.GITHUB_SHA_SHORT }}
Lee Meador
  • 12,829
  • 2
  • 36
  • 42
peterevans
  • 34,297
  • 7
  • 84
  • 83
  • 1
    Removed the extra curly brackets (unnecessary as they become part of the value) and added link to doc. Thanks! – evilSnobu Sep 17 '19 at 09:22
  • 3
    @evilSnobu Not sure if it fits your use case, but there is another similar method for passing values to later steps using `set-output` that I've detailed here. https://stackoverflow.com/questions/57819539/github-actions-how-to-share-a-calculated-value-between-job-steps/57989070#57989070 – peterevans Sep 21 '19 at 04:02
  • what about setting multiple keys and values? Do we just duplicate that same command or is there a way to do it with 1 command? – SudoPlz Apr 28 '20 at 16:04
  • @SudoPlz I think the only way is to duplicate the `set-env` command, yes. You can execute multiple `set-env` commands in the same `run` step, though. – peterevans Apr 28 '20 at 23:14
  • `echo ${{ env.GITHUB_SHA_SHORT }}` I think that is not an alternative syntax, but it uses the Github template engine. That means that you can embed the env variable on places where you usually will not be able to, while `$VARNAME` is only available to shell environment – Danielo515 Jul 10 '20 at 08:41
  • 14
    Just a quick note (since this caused me headache). If you are using a Windows/PowerShell environment, you have to use `$env:GITHUB_ENV`, i.e. something like `run: echo "GITHUB_SHA_SHORT=$(echo $GITHUB_SHA | cut -c 1-6)" >> $env:GITHUB_ENV`. – Carsten Nov 23 '20 at 10:30
  • 25
    BEWARE of the fine print :) "The action that creates or updates the environment variable DOES NOT have access to the new value, but all subsequent actions in a job will have access." – IvanD Feb 19 '21 at 21:14
  • 3
    But what about if I want to use this variable in multiple jobs? Is there any way to define a workflow level variable? – honey_ramgarhia Mar 05 '21 at 04:46
  • I, too, got bitten by the curly braces in the quoted section. – Lee Meador May 28 '21 at 15:47
  • ruby script: `db_url = "postgresql://#{user}:#{RDS_PASSWORD}@#{host}:#{port}/#{db_name}"` this means, then i could set the ENV variable out of a ruby script and then re-use it in another script later in life `DATABASE_URL='#{db_url}' >> $GITHUB_ENV` – Tim Kretschmer Oct 20 '21 at 17:20
  • Github f*ctions become uglier and uglier. Pray for to not ruin it like anything else MS has ruined. – Andry Nov 05 '21 at 14:01
  • 1
    `tee -a` is slightly more useful than `>>`: it shows the newly set environment variable in the output. – krlmlr Dec 07 '21 at 09:38
  • @honey_ramgarhia, I was wondering the same thing and found the answer here: https://stackoverflow.com/a/63485275/13040522 Basically you need to create a workflow env variable, set it in the echo statement and then output it from the job since they run on different virtual machines – Redbeard Sep 28 '22 at 22:41
  • This doesn't answers the question. This works only in `run` part, but how to set the same in `env` for the step? This doesn't work: ``` env: GITHUB_SHA_SHORT: $GITHUB_SHA_SHORT GITHUB_SHA_SHORT: ${{ env.GITHUB_SHA_SHORT }} ``` – lima_fil Dec 31 '22 at 01:11
  • I just printed most of the variables, I couldn't post here because of the length limitation. You can check it out here (Print vars section): https://github.com/wxw-matt/test_release/actions/runs/4587386341/jobs/8100853262 – Fred Apr 02 '23 at 07:02
  • Quick note: For this to work for me, I had to make some changes. What worked for me is adding quotes around $GITHUB_ENV when assigning the variable. That is, `... >> "$GITHUB_ENV"`. And I could only access the variable in a new step, not within the same step in which I assigned the variable. This is the GitHub docs page that I followed: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-writing-an-environment-variable-to-github_env – Tapa Dipti Sitaula Jul 31 '23 at 08:38
5
  - name: Set and Retrieve Github ENV variables
    shell: bash
    run: |

      # define variables      
      tests=16
      failures=2

      # set them as GitHub ENV variables
      echo "Tests=$tests" >> $GITHUB_ENV
      echo "Failures=$failures" >> $GITHUB_ENV

      # retrieve these GitHub ENV variables
      echo "${{ env.Failures }} out of ${{ env.Tests }} tests failed on CI"

Output

  2 out of 16 test failed on CI
Shivam Bharadwaj
  • 1,864
  • 21
  • 23
  • Nice. Is this documented somewhere, could you add a reference? Does it persist for subsequent steps? – evilSnobu May 31 '23 at 13:13
  • @evilSnobu No documentation, this what I'm using – Shivam Bharadwaj Jun 26 '23 at 16:29
  • This isn't working for me. The final output is ` out of tests failed on CI` without the `env.Failures` and `env.Tests` values. – Tapa Dipti Sitaula Jul 31 '23 at 07:45
  • What worked for me is adding quotes around $GITHUB_ENV when assigning the variable. That is, `... >> "$GITHUB_ENV"`. And I could only access the variable in a new step, not within the same step in which I assigned the variable. This is the GitHub docs page that I followed: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#example-of-writing-an-environment-variable-to-github_env – Tapa Dipti Sitaula Jul 31 '23 at 08:36
-7

The documentation https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables#about-environment-variables describes 2 ways of defining environment-variables.

To set custom environment variables, you need to specify the variables in the workflow file. You can define environment variables for a step, job, or entire workflow using the jobs.<job_id>.steps[*].env, jobs.<job_id>.env, and env keywords.

steps:
  - name: Hello world
    run: echo Hello world $FIRST_NAME $middle_name $Last_Name!
    env:
      FIRST_NAME: Mona
      middle_name: The
      Last_Name: Octocat

You can also use the GITHUB_ENV environment file to set an environment variable that the following steps in a workflow can use. The environment file can be used directly by an action or as a shell command in a workflow file using the run keyword.

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170