Share with friends
GitHub Actions is a powerful CI/CD tool for automating your tasks in our development workflows, automating the builds, testing, and deploying the applications.
In particular, GitHub users often leverage environment variables within GitHub Actions to fine-tune their automation.
And so in this article, we will explore the types of GitHub Actions environment variables, their practical use cases, and strategies for defining them, and peek into default environment variables that can enhance your workflows.
But before we move on, here is a sample code that already has an example GitHub Actions workflow file.
The code snippet below shows the contents of the file .github/workflows/pipeline.yml
:
name: Java CI with Maven
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
This file outlines a straightforward Maven build process for our Java application.
The workflow YAML configuration file allows us to declare environment variables at three different levels: workflow, job, and step.
The range of the environment variables is established by these levels. The workflow level makes use of workflow-wide environment variables.
Specific work-specific environment variables are used at the job level. Step-specific environment variables are applicable.
Let's investigate each of these factors in more detail.
Types of GitHub Actions Environment Variables
GitHub Actions provides various types of environment variables, and each of them serves a distinct purpose in your automation workflows.
Let's delve into each of these types with detailed explanations, code snippets, and relevant commands.
Default Environment Variables
Default environment variables are built-in and automatically available for your workflows. These variables are essential for various tasks in your automation pipeline.
Here are some of the commonly used default environment variables:
- GITHUB_TOKEN: This is a critical default environment variable. It's an authentication token with the necessary permissions to perform actions on the GitHub repository.
You can use it to interact with your repository, such as creating issues, pushing code, and triggering workflow runs.
To use it in your workflow, you don't need to define it; it's available by default.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Use GITHUB_TOKEN
run: |
# Use the GITHUB_TOKEN to perform actions on the repository
git commit -m "Automated commit"
git push
- GITHUB_REPOSITORY: This environment variable contains the full name of your repository in the format "username/repo".
You can use it to dynamically reference your repository name within your workflow.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get Repository Name
run: echo "Repository name is ${ { github.repository } }"
- GITHUB_REF: GITHUB_REF stores the Git reference (e.g., branch or tag) that triggered the workflow. It is useful for conditional actions based on the triggering branch or tag.
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check if Pushed to Main
run: |
if [ "${ { github.ref } }" == "refs/heads/main" ]; then
echo "This push is to the main branch."
else
echo "This push is to a different branch."
fi
Secrets
Secrets are a type of environment variable that allows you to securely store sensitive information in your GitHub Actions workflows.
These secrets are used to protect confidential data like API keys, access tokens, or passwords from being exposed in your workflow code or logs.
To use secrets, follow these steps:
-
Defining Secrets
-
Go to your GitHub repository.
-
Click on "Settings" and then select "Secrets."
-
Click on "New Repository Secret" and provide a name and value for your secret.
-
-
Accessing Secrets in Workflow In your workflow YAML file, you can access these secrets using the
secrets
context.
For example, if you have a secret named MY_SECRET_KEY
, you can use it in your workflow like this:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Use Secret
run: echo "My secret key is ${ { secrets.MY_SECRET_KEY } }"
An even more fine-grained approach than the above, let's finish by looking at creating environment variables that are specific for a step within a particular job.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: "Echo"
run: echo "Example of an echo"
- name: "Test to display example_value environment variable"
run: echo "example_value value is $example_value"
env:
example_value: Test-value1
Workflow Environment Variables
Workflow environment variables are specific to a particular workflow and offer a level of isolation and customization.
These variables are defined within your workflow and can be used to store and manage data that is relevant only to that specific workflow.
To define and use workflow environment variables:
1. Defining Workflow Environment Variables
In your workflow YAML file, you can define these variables under the env
keyword.
For example:
jobs:
build:
runs-on: ubuntu-latest
env:
MY_CUSTOM_VAR: "Hello, World!"
steps:
- name: Use Workflow Variable
run: echo "${ { env.MY_CUSTOM_VAR } }"
In this example, we define a custom environment variable MY_CUSTOM_VAR
and use it within the same workflow.
2. Isolation and Customization
Workflow environment variables are isolated from other workflows, allowing you to customize and tailor them to the specific needs of each workflow.
Why?
This isolation helps in organizing and managing variables more effectively.
Use Cases of GitHub Actions Environment Variables
In this section, we will dive into different possibilities of GitHub Actions environment variables.
Triggering Custom Actions
Use Case: You want to trigger different actions within your workflow based on conditions, such as the branch name.
Let's look at an example.
You have a CI/CD pipeline, and you want to deploy to a production environment only when changes are pushed to the main
branch.
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to Production
if: github.ref == 'refs/heads/main'
run: |
# Add deployment steps here
Explanation:
We define a workflow that runs on every push event.
The if
condition checks if the branch reference (github.ref
) matches 'refs/heads/main'
. If it does, the deployment steps are executed.
Dynamic Versioning
Use Case: You want to dynamically generate version numbers for your application based on unique parameters, such as the current date and the commit hash.
Here's an example.
You want to create a version tag that combines the current date and the first eight characters of the commit hash.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set Version
run: |
export APP_VERSION=$(date +"%Y%m%d")-${GITHUB_SHA::8}
env:
APP_VERSION: ${ { env.APP_VERSION } }
Explanation:
In this example, we set a dynamic version number using the date
command and the first eight characters of the GITHUB_SHA
(commit hash).
We store this version number in an environment variable named APP_VERSION
.
Cross-Workflow Communication
Use Case: You need to pass data between different workflows or share information between workflow steps.
Let's look at an example.
You have two workflows: one for building and one for deployment. You want to pass the build status from the build workflow to the deployment workflow.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set Build Output
id: set-output
run: echo "::set-output name=build-output::${ { env.BUILD_OUTPUT } }"
env:
BUILD_OUTPUT: "build_success"
- name: Use Build Output
run: |
# Use the output from the previous step
echo ${ { steps.set-output.outputs.build-output } }
Explanation:
-
In the "Set Build Output" step, we use the
echo "::set-output name=build-output::${ { env.BUILD_OUTPUT } }"
command to set an output variable namedbuild-output
. -
This output variable is defined in the
env
section. -
In the "Use Build Output" step, we retrieve and use the
build-output
value using${ { steps.set-output.outputs.build-output } }
.
Defining Environment Variables in Single Workflow vs Multiple Workflows
When it comes to defining these variables, you have two options: within a single workflow or across multiple workflows. The choice depends on your specific use case and how you want to structure your automation.
Defining Environment Variables in a Single Workflow
When you define environment variables in a single workflow, those variables are available to all the jobs and steps within that particular workflow.
This can be useful in cases where you need to share common data across the entire workflow.
Here's how you can do it:
-
Open your workflow YAML file (e.g.,
.github/workflows/main.yml
) in your repository. -
Define the environment variables under the
env
section at the workflow level.
name: My CI/CD Workflow
on:
push:
branches:
- main
env:
DATABASE_URL: ${ { secrets.DB_URL } }
BUILD_VERSION: 1.0.0
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Build and Test
env:
DATABASE_URL: ${ { env.DATABASE_URL } }
APP_VERSION: ${ { env.BUILD_VERSION } }
run: |
# Use the environment variables defined at the workflow level.
echo "Database URL: $DATABASE_URL"
echo "App Version: $APP_VERSION"
In this example, DATABASE_URL
and BUILD_VERSION
are defined at the workflow level and can be accessed by all the jobs and steps within the workflow.
Defining Environment Variables in Multiple Workflows
Sometimes, you may want to isolate environment variables for different workflows.
This is particularly useful when you have separate workflows for building, testing, and deploying, each requiring distinct configurations.
Here's how to define environment variables in multiple workflows:
-
Create separate workflow YAML files for each distinct workflow (e.g.,
.github/workflows/build.yml
and.github/workflows/deploy.yml
). -
Define the environment variables within each workflow's YAML file.
# build.yml
name: Build Workflow
on:
push:
branches:
- main
env:
BUILD_VERSION: 1.0.0
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Build and Test
env:
APP_VERSION: ${ { env.BUILD_VERSION } }
run: |
# Use the environment variables defined in the 'build.yml' workflow.
echo "App Version: $APP_VERSION"
# deploy.yml
name: Deploy Workflow
on:
push:
branches:
- main
env:
DATABASE_URL: ${ { secrets.DB_URL } }
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to Production
env:
DATABASE_URL: ${ { env.DATABASE_URL } }
run: |
# Use the environment variables defined in the 'deploy.yml' workflow.
echo "Database URL: $DATABASE_URL"
Default Environment Variables
Default environment variables are provided by GitHub Actions and can be accessed in your workflows without any extra configuration.
These variables offer valuable information about your repository and the triggering event.
Let's explore them in a little more detail. Shall we?
GITHUB_TOKEN
GITHUB_TOKEN
is an automatically generated authentication token provided by GitHub Actions. It allows you to interact with your GitHub repository during a workflow run.
Here are a few use cases of this environment variable.
-
Workflow Triggers: You can use
GITHUB_TOKEN
to trigger new workflow runs, like CI/CD pipelines. -
Pull Requests: It's often used to comment on pull requests, update PR status, or even merge PRs automatically.
-
Push Events: You can make changes to your repository, like creating and updating files.
Accessing Other Private Repositories: It can be used to access other private repositories in your organization.
The GITHUB_TOKEN
is automatically created and does not require manual setup.
It has limited permissions, and certain actions like triggering new workflow runs using this token are not allowed to prevent unintentional workflow loops.
GITHUB_REPOSITORY
GITHUB_REPOSITORY
is an environment variable that provides the full name of your repository, including the owner/organization and the repository name.
Here are a few use cases of 'GITHUB_REPOSITORY'.
-
Repository Information: You can use it to gather information about the repository where the workflow is running.
-
Dynamic Configuration: It's helpful when you need to dynamically configure workflow behavior based on the repository's name.
GITHUB_REF
GITHUB_REF
is an environment variable that contains the Git reference (usually a branch or tag) that triggered the workflow.
Here are a few use cases of this GitHub Actions environment variables.
-
Branch-Based Workflows: You can use it to execute specific actions based on the branch name. For example, triggering deployment only for the 'main' branch.
-
Tag Events: It helps in identifying when a tag is pushed, allowing you to perform tag-specific actions.
GITHUB_ACTOR
The GITHUB_ACTOR
variable contains the username of the user or bot that triggered the workflow. You can use this information for user-specific actions or notifications.
GITHUB_WORKFLOW
GITHUB_WORKFLOW
stores the name of the workflow that is currently running. This can be handy if you have multiple workflows and want to differentiate between them.
jobs:
notify:
env:
RUNNING_WORKFLOW: ${ { github.workflow } }
GITHUB_EVENT_NAME
GITHUB_EVENT_NAME
carries the name of the event that triggered the workflow. It's crucial for handling different events with distinct actions in a single workflow.
jobs:
process:
if: ${ { github.event_name == 'push' } }
env:
EVENT_TYPE: ${ { github.event_name } }
GITHUB_SHA
GITHUB_SHA
provides the SHA of the commit that triggered the workflow. This is invaluable for referencing specific commits or for version tracking.
jobs:
build:
env:
COMMIT_HASH: ${ { github.sha } }
Summary of GitHub Actions Environment Variables
The entire GitHub workflow YAML file is displayed in the example below, along with the additional job and step environment variable additions:
name: Java CI with Maven
env:
NAME: 'Snyk Demo'
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
env:
JAVA_VERSION: '11'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK ${ {env.JAVA_VERSION} }
uses: actions/setup-java@v3
with:
java-version: ${ {env.JAVA_VERSION} }
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Print name
run: echo "Hello $NAME. $BUILD. Using Java Version $JAVA_VERSION"
env:
BUILD: 'We are currently running the Build job'
GitHub Actions environment variables allow developers to create dynamic workflows. These variables can be used to modify the workflow's behavior based on user-defined or pre-defined GitHub variables.
Anytime you want to dynamically alter the workflow, or a particular job or stage, as well as when they should run, we should use GitHub Actions environment variables.
Share with friends