Github Actions Outputs
Cannot pass information between jobs in Github Actions if it contains secret values
Passing information between Github actions steps is one of the most necessary feature. Github Actions supports multiple way of doing this. Normally a job is a seperated environment. It means you cannot reach the resources between jobs. However sometimes you need to transfer some information and files between jobs and steps in order to shape the workflows behaviour.
Github Actions allows us multiple ways to do it. I will mention most of the used ones before i get to the point. These are;
- Artifacts
- Environment Variables
- Job Outputs
These 3 methods are widely used and covers most of the need. Let’s quickly have a recap on these.
Artifacts
Most of the workflows produces some kind of files such as docker images, configuration files, caches etc. After the producement of these files we might want to use them in the subsequent jobs or steps. If we are going to use them in the same job, there is no problem. Because the job uses the same storage and files are located in our runner (Machine that executes our worklow). However if they are needed in the other jobs we cannot get these files unless they are running in the same machine.
To overcome this problem we can use the Artifacts Actions. With Github developed actions/upload-artifact
and actions/download-artifact
we can achive this goal. As an example following workflow configuration allows us to transfer files under tey/.hidden
folder and use them in the next job.
on: workflow_dispatch
name: Upload/Download Artifacts
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Create a File
run: echo "hello-changed" > hello.txt
- name: Replace Character in env save it o new env and pass to other step
id: replace-chars
run: |
mkdir tey
mkdir tey/.hidden
mv hello.txt tey/.hidden/hello.txt
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: test-12345
path: tey/.hidden
download:
runs-on: ubuntu-latest
needs: upload
env:
pathmodified: ${{needs.upload.outputs.artifact-name}}
steps:
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: test-12345
- name: Print Artifact
run: |
cat hello.txt
Environment Variables
In Github Actions every step is getting executed by it’s own shell. It means environment variables are defined in one step might not be able to be transferred to another step. In order to solve this GITHUB_ENV
is used. You can transfer your envs to this file and Github will load your env variables in the next steps.
echo "pathmodified=$pathmodified" >> $GITHUB_ENV
Outputs
Outputs is also a way to share info between jobs. So it is useful when you only need to transfer an information rather than an artifact. As an example following workflow transfer a information which is called message
to second-run
job.
---
on: workflow_dispatch
name: Share Info between jobs
jobs:
first-run:
runs-on: ubuntu-latest
outputs:
message: ${{steps.echo.outputs.message}}
steps:
- name: Echo
id: echo
run: |-
echo "message=merhaba" >> $GITHUB_OUTPUT
second-run:
runs-on: ubuntu-latest
needs: first-run
steps:
- name: Echo
id: alpha
run: echo ${{ needs.first-run.outputs.message }}
Pain Points of Outputs
It worked smoothly until i had an experience about failing to transfer an output. I tried everything such as removing the dash from output name or setting output before supplying them to GITHUB_OUTPUT
. None of them worked until i have figured it out from documentation Github Actions Outputs.
At the end if some parts of your outputs has an secret, it will be masked by runners and it cannot be passed to outputs. In case of having a secret like 12345
you will not able to transfer outputs such as test12345
. This behaviour is obviously designed for protection of the secrets so in order to not getting blocked by a situation like this, make sure that you are not using common words in your secrets such as linux
or arm
.