Tidbit
- devops|
- productivity
GitHub Actions step outputs
Guy Waldman
July 12, 2024
Time to read:
3 minutes
So you've created a GitHub Actions workflow and you want to reuse the output of one step in another step.
I present an easy way to do that.
Suppose we have the following workflow:
NoteThis is a simplified example with better ways to do this, but it should hopefully convey the main idea.
1name: My workflow 2 3on: 4 pull_request: 5 branches: [dev, main, release-*] 6 7jobs: 8 test: 9 name: Run tests 10 steps: 11 # ... (omitted) 12 13 - name: Run tests 14 run: npm test 15 env: 16 CPU_CORES: 8 # TODO: Get this from the actual CI environment. 17 18 # ... (omitted) 19
OK, and now you want to handle that
So you write a small script that does this in a cross-platform way (let's say only UNIX-like systems) and call it
TODO
, and populate CPU_CORES
according to the actual system you're running the test on.So you write a small script that does this in a cross-platform way (let's say only UNIX-like systems) and call it
get-cpu-cores.sh
.1# ... (omitted) 2 3jobs: 4 test: 5 name: Run tests 6 steps: 7 # ... (omitted) 8 9 - name: Get CPU cores 10 run: ./get-cpu-cores.sh 11 12 - name: Run tests 13 run: npm test 14 env: 15 CPU_CORES: ??? # TODO: Get this from the actual CI environment. 16 17 # ... (omitted) 18
So now how do we get the output of the
get-cpu-cores.sh
script?
If you want to run it and retain the output, you could do it in a number of ways, but GitHub Actions has a nice built-in way to pass along the outputs of a step:1# ... (omitted) 2 3jobs: 4 test: 5 name: Run tests 6 steps: 7 # ... (omitted) 8 9 - name: Get CPU cores 10 id: get-cpu-cores 11 run: ./get-cpu-cores.sh | { read cores; echo "cpu-cores=$cores" } >> $GITHUB_OUTPUT 12 13 - name: Run tests 14 run: npm test 15 env: 16 CPU_CORES: ${{ steps.get-cpu-cores.outputs.cpu-cores }} 17 18 # ... (omitted) 19
As you can see, we're reading the output of the
get-cpu-cores.sh
script, and appending cpu-cores=<OUTPUT>
(that's what the | { read cores; echo "cpu-cores=$cores" }
part does) to the $GITHUB_OUTPUT
variable.You can think of this as an
.env
file which contains a key-value mapping of outputs from different stpes, and you can append to that.
GitHub knows how to parse it and use it as an output for the step with the ID get-cpu-cores
.You can also get more sophisticated! This can now be used as other variables in GitHub Actions, for example only runing steps according to the output of the script:
1# ... (omitted) 2 3jobs: 4 test: 5 name: Run tests 6 steps: 7 # ... (omitted) 8 9 - name: Get CPU cores 10 id: get-cpu-cores 11 run: ./get-cpu-cores.sh | { read cores; echo "cpu-cores=$cores" } >> $GITHUB_OUTPUT 12 13 - name: Run tests 14 run: npm test 15 env: 16 CPU_CORES: ${{ steps.get-cpu-cores.outputs.cpu-cores }} 17 18 - name: Run heavy tests 19 run: npm run heavy-tests 20 if: steps.get-cpu-cores.outputs.cpu-cores > 8 21 22 # ... (omitted) 23
This is an example scenario where you run the CI on a matrix of different machines and you want to run the "heavy tests" only on more bulky ones.
Related content
- productivity|
- ai
Introducing: magic-cliPostJuly 16, 2024A command line utility that will make you a magician in the terminal- technical|
- productivity
Git hooks for fun & profitPostAugust 9, 2022Using git hooks for developer workflow automation- opinion|
- productivity|
- ai
The future of software developmentPostJune 29, 2021What will the future of software tooling look like?- technical|
- productivity
Loading .env files with no dependenciesTidbitJuly 26, 2024Loading .env files easily in *NIX shells with no dependencies- ide|
- productivity
Quickfix in VS CodeTidbitJuly 18, 2024How to create a VS Code shortcut or vim binding to apply the first quickfix suggestion