Environment Files

I just noticed the deprecation warning concerning the use of “set-env” in a workflow. The linked documentation describes the use of Environment Files as a replacement. I have not tried using these yet, but I notice that the docs read “all subsequent actions in a job will have access” to the created env variable. Will the variable also be available to other jobs as well?

No, just within the same job. If you want to transfer data between jobs you can use job outputs or artifacts, depending on complexity.

It doesn’t seem to be possible to share the environment file of one job with a dependent job. Here’s my test setup:

on: issue_comment

jobs:
  commented:
    name: Issue/PR commented
    runs-on: ubuntu-latest
    outputs:
      gh-env: ${{ steps.shared-env.outputs.gh-env }}
    steps:
      - name: Set env var
        id: shared-env
        run: |
          echo 'ENV_VAR=foo bar' >> $GITHUB_ENV
          echo "::set-output name=gh-env::$GITHUB_ENV"
  post:
    name: Post job
    needs: commented
    runs-on: ubuntu-latest
    steps:
      - name: Get env from other job
        run: |
          echo "$GITHUB_ENV"
          echo '----------'
          echo '${{ needs.commented.outputs.gh-env }}'
          echo '----------'
          cat '${{ needs.commented.outputs.gh-env }}'
          echo '----------'
          cat '${{ needs.commented.outputs.gh-env }}' >> $GITHUB_ENV
      - name: Copied env vars
        run: |
          echo "$ENV_VAR"

The first job’s GITHUB_ENV path is shared with the second job, but the file doesn’t exist anymore when the second job runs:

cat: /home/runner/work/_temp/_runner_file_commands/set_env_5e257de5-b756-4185-accd-b61b0bf3af54: No such file or directory

I also tried to set the content of the file as output, but it got lost on its way to the second job for some reason…

How strange. I added some log information and the environment file appears to be a regular file that is readable and writable. Neither cat, tail nor $(<file) return anything if I try to get its content however:

    steps:
      - name: Set shared env var
        id: set-github-env
        run: |
          echo 'ENV_VAR_1<<EOF' >> $GITHUB_ENV
          echo 'foo' >> $GITHUB_ENV
          echo 'bar' >> $GITHUB_ENV
          echo 'do not eval `this`' >> $GITHUB_ENV
          echo 'EOF' >> $GITHUB_ENV
          echo 'ENV_VAR_2=single line' >> $GITHUB_ENV
      - name: Set env as output
        id: set-env-output
        run: |
          echo "ENV_VAR_1 = $ENV_VAR_1"
          echo "ENV_VAR_2 = $ENV_VAR_2"
          echo "Env file: $GITHUB_ENV"
          ls -la $GITHUB_ENV
          if [[ -e $GITHUB_ENV ]]; then echo 'exists'; fi
          if [[ -r $GITHUB_ENV ]]; then echo 'readable'; fi
          if [[ -w $GITHUB_ENV ]]; then echo 'writable'; fi
          if [[ -s $GITHUB_ENV ]]; then echo 'size greater than zero'; fi
          if [[ -f $GITHUB_ENV ]]; then echo 'is regular file'; fi
          if [[ -h $GITHUB_ENV ]]; then echo 'is symbolic link'; fi
          if [[ -p $GITHUB_ENV ]]; then echo 'is named pipe'; fi
          if [[ -S $GITHUB_ENV ]]; then echo 'is socket'; fi
          echo "Content (cat): $(cat $GITHUB_ENV)"
          echo "Content (tail): $(tail $GITHUB_ENV)"
          echo "Content (redirect): $(<$GITHUB_ENV)"

Log:

ENV_VAR_1 = foo
bar
do not eval `this`
ENV_VAR_2 = single line
Env file: /home/runner/work/_temp/_runner_file_commands/set_env_90fefe61-b4a3-4cf4-9cf8-e6ad5c30b6b3
-rw-r--r-- 1 runner docker 0 Oct 13 09:57 /home/runner/work/_temp/_runner_file_commands/set_env_90fefe61-b4a3-4cf4-9cf8-e6ad5c30b6b3
exists
readable
writable
is regular file
Content (cat): 
Content (tail): 
Content (redirect): 

Is it possible that there is a process which tails the file and immediately truncates it after it read what a job wrote to the file?

Related: How to share shell profile between steps? (or: how to use nvm/rvm in steps?)