I'm creating a GitHub Actions workflow for my CI and I realize that I'm repeating some piece of information. For example, the runs-on
of a job is defined as ubuntu-18.04
and mac-10.14
, or a specific compiler/toolchain version in a strategy/matrix
.
I'd like to centralize those version information somewhere in the YAML file and be able to refer to these instead of duplicating the value many times. That way I don't repeat myself (DRY) and I can easily change the version value at a single location and prevent inconsistencies.
Unfortunately I have trouble doing so. The way I though could be used for this is to use a global env
environment variable at the top of the YAML and refer to it elsewhere. For example, I would like to replace something like the following:
on: [push, pull_request]
name: CI
jobs:
build:
name: Build
runs-on: ubuntu-18.04
strategy:
matrix:
toolchain:
- 1.2.3
steps:
- run: ./build.sh 1.2.3
package:
name: Package
runs-on: ubuntu-18.04
steps:
- run: ./package.sh 1.2.3
[...]
with:
on: [push, pull_request]
name: CI
env:
UBUNTU_VERSION: 18.04
TOOLCHAIN_VERSION: 1.2.3
jobs:
build:
name: Build
runs-on: ubuntu-${{ env.UBUNTU_VERSION }}
strategy:
matrix:
toolchain:
- ${{ env.TOOLCHAIN_VERSION }}
steps:
- run: ./build.sh ${{ matrix.toolchain }}
package:
name: Package
runs-on: ubuntu-${{ env.UBUNTU_VERSION }}
steps:
- run: ./package.sh ${{ env.TOOLCHAIN_VERSION }}
[...]
i.e. use the env
context in an expression (see Contexts and expression syntax for GitHub Actions - Contexts).
This fails with:
### ERRORED 18:08:15Z
- Your workflow file was invalid: The pipeline is not valid. .github/workflows/ci.yml (Line: 20, Col: 14): Unrecognized named-value: 'env'. Located at position 1 within expression: env.UBUNTU_VERSION,.github/workflows/ci.yml (Line: 125, Col: 14): Unrecognized named-value: 'env'. Located at position 1 within expression: env.UBUNTU_VERSION
I could only find this question on the env
context and this page saying the env
now works on the workflow level.
How can I centralize repeating strings/versions/etc. into a single location as to DRY?
Thanks!
You can do this at the workflow level using env
, you just can't use those values inside the runs-on
- which is why you've only got errors for UBUNTU_VERSION
and not TOOLCHAIN_VERSION
.
Why? Because env
is an environment variable which is set on the machine but it needs to provision the machine before it can set an environment variable on the machine, but it doesn't know which machine to provision because you have an env var in the machine type.. :)
I'm sure GitHub COULD fix this but it doesn't work right now.
Side note: jobs are designed to be run independently, in parallel and on different machines. If you have a sequential workflow it's better to have a single job and multiple steps. That would also get rid of your repeating ubuntu-18.04
definitions and shrink your workflow file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With