How to set variables conditionally in Github Actions » 08 March 2023

I’ve noticed my Github Actions workflows look awfully similar to each other in prod and staging. To be honest these workflows have never really gone through careful planning, I’ve kept adding stuff to them as needed. Since the two workflows do pretty much the same, it’d make sense to merge them. Keep in mind that this is just an example, setting env variables based on a condition comes handy quite often even if you don’t have separate environments.

Step one, amend the worklow so that it’s triggered by both branches:

on:
  push:
    branches: ["master", "staging"]
  workflow_dispatch:

Setting a variable is fairly easy. All you have to do is to create a new step and run:

echo "KEY=value" >> $GITHUB_ENV

Now to assign the appropriate value based on the branch name, you have to create two steps, and use if: to check which one needs to be executed. In our case the new steps would look like this:

- name: "Generate image tag for production site"
  if: ${{ github.ref == 'refs/heads/master' }}
  run: |
    echo "DOCKER_TAG=some-registry.pkg.dev/project-id/repository-id/image-name:latest" >> $GITHUB_ENV

- name: "Generate image tag for staging site"
  if: ${{ github.ref == 'refs/heads/staging' }}
  run: |
    echo "DOCKER_TAG=some-registry.pkg.dev/project-id/other-repository-id/image-name:latest-staging" >> $GITHUB_ENV

Technically it would make sense to only store latest or staging in the env var, but the full tag gets reused quite a few times across the workflow, so it was easier this way.

You can also chain assignments together, so you don’t have to create a new step for every variable, e.g.:

echo "SERVICE_NAME=example-prod" >> $GITHUB_ENV && echo "BASE_URL=example.com"

You can then use ${{ env.KEY }} to access the variable, like this:

- name: Create Docker image
  run: "docker build -t ${{env.DOCKER_TAG}} ."

That’s pretty much it, though you may also want to look into a bit more refined approach and use Git tags. Such a condition would look like this:

if: startsWith(github.ref, 'refs/tags/release-')