Introduction
In GitHub Actions, variables store reusable, nonsensitive information like usernames, paths, or configurations. A variable can be scoped to a single workflow or across multiple workflows so that it is easy to maintain settings that might be different across various environments. Outside of this, GitHub has set a few default environment variables that we can use in various of our actions, or could define our own custom ones. And we can also fetch the values of these variables anywhere inside our workflow using contexts.
Why is it useful?
That way, this will simplify the configurations within our workflows. We are not going to hard-code values but instead declare some variables and then reuse their values throughout the steps or jobs in order for the workflows to be more maintainable or debuggable. After that, we could then have more flexibility regarding maintenance for various environments, whereby this would reduce the possibilities of errors from manual entries.
Using ENV variables
Custom Variables
You may declare environment variables at a scope of workflow, job, or step. Here's how:
// ".github/workflows/env-variables.yml"
name: Greeting on variable day
on:
workflow_dispatch
env:
DAY_OF_WEEK: Monday # Workflow level variable
jobs:
greeting_job:
runs-on: ubuntu-latest
env:
Greeting: Hello # Job level variable
steps:
- name: "Say Hello Mona it's Monday"
run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
env:
First_Name: Mona # Step level variable
Accessing Variables
The Variables can be accessed using Environment variables or using contexts in other parts of the workflow. It is possible for example to access as:
run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
If you want to access them via contexts instead of directly as environment variables, use the following:
run: echo "${{ env.Greeting }} ${{ env.First_Name }}. Today is ${{ env.DAY_OF_WEEK }}!"
Security Concerns
Variables aren't masked in output so for passwords or API keys you should utilize GitHub Secrets. As an example, to access secrets you would normally do something like:
steps:
- name: Use secret
run: echo "Your secret is ${{ secrets.MY_SECRET }}"
Configuration Variables
These can be reused in multiple workflows using the organization, repository, or environment levels. They are referenced using the vars context.
on: workflow_dispatch
env:
env_var: ${{ vars.ENV_CONTEXT_VAR }} # Access configuration variables
jobs:
display-variables:
runs-on: ${{ vars.RUNNER }}
steps:
- name: Show variables
run: |
echo "Repo variable: $REPOSITORY_VAR"
echo "Org variable: $ORGANIZATION_VAR"
echo "Overridden variable: $OVERRIDE_VAR"
env:
REPOSITORY_VAR: ${{ vars.REPOSITORY_VAR }}
ORGANIZATION_VAR: ${{ vars.ORGANIZATION_VAR }}
OVERRIDE_VAR: ${{ vars.OVERRIDE_VAR }}
Passing Data Between Jobs
If there is a need to pass values across jobs or steps, then that's where you'll be using the job outputs. Here's how:
jobs:
job1:
runs-on: ubuntu-latest
steps:
- name: Generate value
id: step1
run: echo "::set-output name=my_var::Hello World"
job2:
needs: job1
runs-on: ubuntu-latest
steps:
- name: Use value from job1
run: echo "The value is ${{ steps.step1.outputs.my_var }}"
Setting ENV variables
Creates or updates an environment variable for any actions running next in a job. The action that creates or updates the environment variable can't access the new value, but all subsequent actions in a job will have access. Environment variable names are case-sensitive and you can use punctuation.
- name: Set env
run: echo "GITHUB_SHA_SHORT=$(echo $GITHUB_SHA | cut -c 1-6)" >> $GITHUB_ENV
- name: Test
run: echo $GITHUB_SHA_SHORT
Conclusion
Environmental and configuration variables, on the other hand, reduce the overhead of managing workflows and decrease the complexity of GitHub Actions. Whether you have to use variables across multiple workflows or protect sensitive information stored in secrets, variables are flexible and reusable solutions that will minimize errors and improve maintainability.