Github Actions Environment Variables

Viewed 30

I'm sure this must be really simple, but I just can't see it and would appreciate any assistance.

Lets say I have a really simple pipeline like this:

name: Deploy to App Engine

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  PROJECT_ID: stankardian
  REGION: europe-west2
  APP_NAME: tootler

jobs:
  deploy:
    name: Test Deployments To App Engine
    runs-on: ubuntu-latest

    steps:
      # Checkout the repo code:
      - name: Checkout repository
        uses: actions/checkout@v3
        with:
          ref: main

What I am trying to do is re-use the same pipeline for multiple deployment scenarios where the deployment steps can can the same, but I need to be able to use different values in the deployment steps.

For example the APP_NAME below is 'tootler'. Lets say I need to deploy this to dev, test and preprod. For dev the app name would be 'dev-tootler', in test it would be 'test-tootler, but in preprod it might need to be 'preprod-tootler-v4' or some such.

Ideally I would like to set a single variable somewhere to control the environment I'm deploying into then depending on the value of that variable then load a range of other environment variables with the specific values pertaining to that environment. The example is grossly simplified, but I might need to load 40 variables for each environment and each of those might be a different value (but the same env variable name).

In an ideal world I would like to package the env variables and values in the app directory and load the correct file based on the evaluation of the control variable. E.g.

|
|-- dev.envs
|-- test.envs
|-- preprod.envs

along with :

$env_to_load_for = $env:control_variable
load_env_variables_file($env_to_load_for)

In that pseudocode the value of $env_to_load_for evaluates to the correct filename for the environment I need to work with,then the correct environment varibles get loaded.

I have tried running a bash shell script which exports the variables I need, but I'm finding that those variables only exist for the specific step in the pipeline. By the time I list out the environment variables in the next step, they are gone.

Does that makes sense? This kind of scenario must be very common, but I cant seem to locate any patterns that explain how to accomplish this. I don't want to do down the route of managing different yaml files per environment when the actions are identical.

Would be very grateful for any assistance.

1 Answers

After a lot of experimentation I think I came up with a good way to achieve this. Posting as an answer in case this information helps someone else in the future.

What I did was:

  1. Add a bash step immediately after the checkout
  2. Use that step to run a shell script, I called the script 'target_selector.sh'
  3. In 'target_selector.sh' I evaluate an existing environment variable which I set already at either the job or workflow scope. This is set to either 'dev', 'test' or 'preprod' and wil be used to set the context for everything in one single easy to manage value.
  4. I used a case block to then, depending on the value of that variable, dot source either 'dev.sh', 'test.sh' or 'preprod.sh' depending on what was evaluated. These files I put in a /targets folder.
  5. This is where the magic happens, in those .sh files (in the /targets folder), I added the environment variables I need, for that context, using this syntax:
echo "DEPLOY_TARGET=dev" >> $GITHUB_ENV
echo "APP_NAME=dev_appname" >> $GITHUB_ENV

Turns out that this syntax will write the output of the expression up to the workflow scope. This means that subsequent steps in the workflow can use those variables.

Its a little bit of a faff, but it works and is clearly extremely powerful.

Hope it helps someone, someday.

Related