Persist output
How to capture output from one step and reuse in a later step or another job
See more info the GH Actions Set up Go section of my Code Cookbooks.
Using GitHub env file
From Environment Variables in the docs.
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.
That links to 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.
steps:
- name: Set the value
id: step_one
run: echo "action_state=yellow" >> $GITHUB_ENV
- name: Use the value
id: step_two
run: echo "${{ env.action_state }}" # This will output 'yellow'
Examples
Get a version from a file and use it as a parameter for an action in another step.
steps:
- name: Get Go version
run: echo "GO_VERSION=$(grep ...)" >> $GITHUB_ENV
- uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
Use step variable output
Syntax
Note that set-output
and save-state
are deprecated - see post.
- name: Set output
run: echo "{name}={value}" >> $GITHUB_OUTPUT
# Deprecated
- name: Set output
run: echo "::set-output name={name}::{value}"
Plain text:
echo "GREETING=hello" >> $GITHUB_OUTPUT
# Deprecated
echo "::set-output name=GREETING::hello"
Variable:
echo "GREETING=$MY_VAR" >> $GITHUB_OUTPUT
# Deprecated
echo "::set-output name=GREETING::$MY_VAR"
Expression - use a subshell.
echo "GREETING=$(grep ...)" >> $GITHUB_OUTPUT
# Deprecated
echo "::set-output name=my_value::$(grep ...)"
Or in two steps:
MY_VAR="$(grep ...)"
echo "name=my_value::$MY_VAR" >> $GITHUB_OUTPUT
Reuse across steps. My trimmed down example from the docs example.
steps:
- id: step1
run: echo "name=hello" >> $GITHUB_OUTPUT
- id: step2
run: echo "name=test::world" >> $GITHUB_OUTPUT
- name: Display
run: |
echo "Step 1 test: ${{ steps.step1.outputs.test }}"
echo "Step 2 test: ${{ steps.step1.outputs.test }}"
Donโt forget to set and use the id
attributes. If you only have one step with variables set, that typically has the id
of vars
. See below.
Examples
Get output from npm outdated
command, if any.
Note using of single quotes to handle multi-line output.
steps:
- name: Check for outdated packages
id: vars
run: |
OUTDATED=$(npm outdated) || true
echo "OUTDATED='$OUTDATED'" >> $GITHUB_OUTPUT
- name: Upgrade
if: ${{ steps.vars.outputs.OUTDATED != '' }}
run: npm upgrade
Get Go version from go.mod
, using set-output
method.
steps:
- name: Get Go version
id: vars
run: |
echo "::set-output name=go_version::$(grep '^go' go.mod | egrep -o '(\d\.\d+)')"
echo "Using Go version ${{ steps.vars.outputs.go_version }}"
- name: Set up go
uses: actions/setup-go@v2
with:
go-version: ${{ steps.vars.outputs.go_version }}
Handle Yarn cache directory path. We run yarn cache dir
command and store and retrieve the value. From Yarn guide.
steps:
- name: Get yarn cache
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
Pass between jobs
From docs.
A map of outputs for a job. Job outputs are available to all downstream jobs that depend on this job.
Outputs containing secrets are redacted on the runner and not sent to GitHub Actions.
Syntax
This docs example shows how to reuse values across steps and across jobs. You only need to set up the outputs
section for reuse across jobs.
main.yml
jobs: job1: runs-on: ubuntu-latest outputs: output1: ${{ steps.step1.outputs.test }} output2: ${{ steps.step2.outputs.test }} steps: - id: step1 run: echo "::set-output name=test::hello" - id: step2 run: echo "::set-output name=test::world" - name: Display run: echo "${{ steps.step1.outputs.test }}" job2: runs-on: ubuntu-latest needs: job1 steps: - run: echo ${{ needs.job1.outputs.output1 }} ${{ needs.job1.outputs.output2 }}
Returning a JSON object - from docs.
main.yml
jobs: job1: runs-on: ubuntu-latest outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: - id: set-matrix run: echo '::set-output name=matrix::{"include":[{"project":"foo","config":"Debug"},{"project":"bar","config":"Release"}]}' job2: needs: job1 runs-on: ubuntu-latest strategy: matrix: ${{ fromJSON(needs.job1.outputs.matrix) }} steps: - run: build