English

Share with friends

Note

GitHub Actions is a powerful CI/CD tool for automating your tasks in our development workflows, automating the builds, testing, and deploying the applications.

How to Use GitHub Actions Environment Variables - A Complete Guide cover image

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:

  1. 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
  1. 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 } }"
  1. 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:

  1. 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.

  2. 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 named build-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:

  1. Open your workflow YAML file (e.g., .github/workflows/main.yml) in your repository.

  2. 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:

  1. Create separate workflow YAML files for each distinct workflow (e.g., .github/workflows/build.yml and .github/workflows/deploy.yml).

  2. 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.

  1. Workflow Triggers: You can use GITHUB_TOKEN to trigger new workflow runs, like CI/CD pipelines.

  2. Pull Requests: It's often used to comment on pull requests, update PR status, or even merge PRs automatically.

  3. 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.

Note

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

Priyansh Khodiyar's profile

Written by Priyansh Khodiyar

Priyansh is the founder of UnYAML and a software engineer with a passion for writing. He has good experience with writing and working around DevOps tools and technologies, APMs, Kubernetes APIs, etc and loves to share his knowledge with others.

Further Reading

Life is better with cookies 🍪

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt out if you wish. Cookie Policy