How to Use Github Actions Environment Variables

Github Actions Environment Variables

What Are Github Actions Environment Variables? 

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that automates development pipelines, from the build stage through to testing and deployment. 

GitHub Actions organizes pipelines using the concept of workflows. For each workflow, there is a set of default environment variables, and you can declare additional custom variables within your workflow file. Environment variables can be used to store and reference data throughout your workflow. They are usable within the context of a workflow step, a job, or a specific action, and are evaluated on the runner machine executing your workflow.

To specify a custom environment variable, you can use the env key in the workflow file. The scope of a variable defined this way is limited to the element where it is declared: 

  • If you want the variable to affect the entire workflow, add the env key at the root level of the workflow file.
  • For a specific job within a workflow, use jobs.<job_id>.env
  • For a particular step within a job, use jobs.<job_id>.steps[*].env

Another important type of environment variables is secrets. When you store an environment variable as a secret, GitHub Actions stores it securely, to avoid sensitive information from being compromised by attackers.

What You Can Do with Environment Variables in GitHub Actions 

Configuring Build Parameters Dynamically

When you are building a software application, you often need to adjust certain parameters based on the environment in which the build is running. For instance, you might need to adjust the level of logging based on whether you’re running a debug build or a release build. Or you might want to use different API endpoints based on whether you’re building for a testing environment or a production environment.

You can use Github Actions environment variables to set these parameters dynamically, based on the context of the build. This allows you to have a single, unified build process for all environments.

Managing Deployment Credentials Securely

When you’re deploying your application, you often need to provide sensitive information like API keys, database passwords, or SSH keys. You should never store this sensitive information directly in your code or your workflow files—this can lead to security breaches if your code is ever exposed. 

Instead, you should store this information using secrets, a type of GitHub Actions environment variable. GitHub Actions securely encrypts secrets and ensures they can only be accessed by authorized workflows. This way, your sensitive information is kept secure, and you can manage your deployment credentials in a single, centralized location.

Parameterizing Test Runs

When you’re running automated tests, you often want to run the same test suite with different parameters. For example, you might want to test your application with different versions of a dependency, or with different configuration settings. You might also want to run your tests in different environments.

In these cases, you can use environment variables to provide these parameters to your test runs. This allows you to easily customize your test runs without having to modify your test code or your test configuration files.

Learn more in our detailed guide to testing environments

Handling Multi-Environment Deployments

When you’re deploying your application, you often need to deploy to multiple environments, like a testing environment, a staging environment, and a production environment.

Each of these environments might have different configuration settings, different API endpoints, or different deployment credentials. By using environment variables, you can easily customize your deployment process for each environment, without having to maintain separate deployment processes for each one.

Common Types of Environment Variables in GitHub Actions  

Environment variables in GitHub Actions can be defined at various levels, each with its own set of rules and purposes. Let’s explore these different types to better understand their roles and how they can be applied in your workflows.

Default

Default environment variables are automatically set by GitHub Actions. These are available to every step in a workflow run and hold key information about the repository, workflow, runner, and more. Note that you cannot modify the values of these default variables.

For example, the GITHUB_REPOSITORY variable contains the name of the repository where the workflow is running, while GITHUB_RUN_ID stores a unique number for each run of a particular workflow.

Workflow

Workflow environment variables are custom variables you define in your workflow file, by adding the env key at the root level of the workflow file. Unlike default environment variables, you have full control over these, including their names and values.

Workflow environment variables are available to all jobs and steps within the workflow. This makes them ideal for storing values that are used across multiple jobs or steps. For instance, you might create a workflow variable to hold the version number of a software package that your workflow is building, testing, or deploying.

Job

Job environment variables are custom values that you define in your workflow files as follows: jobs.<job_id>.env. These are scoped to a particular job within the workflow. They are only available to the steps within the job where they are defined.

Job environment variables allow you to tailor the behavior of individual jobs in your workflow. For example, you might define a job variable to specify a different build configuration for each job in a matrix build.

Step

Step environment variables are the most granular type of environment variables. You define them in a workflow file as follows: jobs.<job_id>.steps[*].env. These variables are defined at the step level and are only accessible within a specific step.

Step variables are perfect for controlling the behavior of individual steps. For example, you might use a step variable to pass a command-line argument to a script that is run within the step.

Secrets

Secrets are a special type of environment variable used to store sensitive data, like API keys, passwords, or credentials. They provide a secure way to use sensitive data in your workflows without exposing it in your workflow file or in the log output of your workflow runs. 

You can create secrets in the GitHub Actions web interface by navigating to Settings > Security > Secrets and variables, select the Secrets tab, and click New repository secret.

Github actions secrets and variables

Source: GitHub

Secrets are encrypted and can only be accessed by steps in your workflow that have been explicitly granted access. They can be defined at the level of a repository, an organization, or an environment.

Tips From the Expert

In my experience, here are tips that can help you better use GitHub Actions environment variables:

  1. Leverage matrix builds with environment variables
    Use matrix builds to run multiple jobs with different environment variables (e.g., testing different dependency versions). This can drastically reduce workflow complexity by automating parallel job execution based on variable combinations.

  2. Avoid hardcoding workflow variables
    Define shared environment variables in reusable workflow templates (.github/workflows) or at the repository level to maintain consistency across multiple workflows. This also reduces duplication and makes future updates easier.

  3. Mask sensitive information in logs
    Use the ::add-mask:: command to prevent sensitive environment variables from being exposed in logs. This is especially useful for debugging jobs without leaking sensitive data like API keys or tokens.

  4. Use the GITHUB_ENV file for dynamic variable assignment
    For setting environment variables dynamically during a workflow run, leverage the GITHUB_ENV file. This allows you to export variables between steps or jobs, especially when dealing with values generated at runtime.

  5. Set conditional environment variables using expressions
    Use GitHub Actions expressions to dynamically set environment variables based on conditions (e.g., branch, event type). This is useful for customizing behavior based on CI/CD triggers like pull_request vs push events.

Ran Cohen photo
Ran Cohen
CTO & Co-Founder. Configu
Before co-founding Configu, Ran was a full stack developer at Testim.io and previously served in an elite cybersecurity unit in the Israeli Defense Forces.

Quick Tutorial: Defining Github Actions Environment Variables and Secrets 

Define an Environment Variable for a Step

One of the simplest ways to define an environment variable is to declare it directly in a step. Here’s an example. 

- name: Example step
  env: 
    DATABASE_URL: MyURL
  run: | 
    echo This is the database URL: $DATABASE_URL

Here, you declare variables using the env key above the script. Use this syntax if you know the values of each variable at the beginning of the script.

Another way is to declare the environment variable directly within the step. It can then be used multiple times within it. This method is useful when you define variables throughout your scripts.

- name: Example step
  run: | 
    DATABASE_URL=MyURL
    echo This is the database URL: $DATABASE_URL

Define an Environment Variable for Entire Job

There may be cases where you want to define an environment variable to reuse it multiple times across your jobs, such as a build configuration or a file suffix. In such cases, you need to define it globally within the job. The env property at the job level allows you to do this:

job1: 
  runs-on: ubuntu-latest 
  env: 
    BUILD_CONFIG: MyConfig
  steps: 
    - name: Example step
      run: echo This is the build configuration: $BUILD_CONFIG

As explained above, you can reuse the BUILD_CONFIG environment variable across multiple steps in your job.

Define Environment Variable for Entire Workflow

If your workflow consists of multiple jobs, you may need to share some global variables between each job. There is an env property available at the workflow level that you can use:

name: Example workflow
on: 
  push: 
    branches: [main]
env: 
  BUILD_CONFIGURATION: Release
jobs: 
  job1: 
    runs-on: ubuntu-latest 
    steps: 
      - name: Example step 
        run: echo This is the build configuration stored in a global workflow variable: $BUILD_CONFIGURATION 
  job2: 
    needs: job1 
    runs-on: ubuntu-latest 
    steps: 
      - name: Example step
        run: echo Here too we can see the same build configuration: $BUILD_CONFIGURATION

The BUILD_CONFIGURATION variable is now defined for the entire workflow and is used in both job1 and job2.

Encode a File Using Base64 and Save as a Secret

If you need to use sensitive data in your environment variables, you should use the GitHub Actions secrets feature. This allows you to securely store these files within GitHub Actions. You should never store certificates and passwords directly in your GitHub repositories, as they will be exposed to attackers if they see your code.

To create a new secret, navigate to Settings > Security > Secrets and variables, select the Secrets tab, and click New repository secret (you can also create a secret at the organization or environment level).

If your secret is a short string, such as a password, you can save it directly in the GitHub Actions interface. However, when dealing with entire files, such as certificates, you cannot directly upload them to this interface. So you’ll need to convert the file into a base64 string. Here is how to do this on Ubuntu:

base64 data.txt > data.b64

You can then securely store the resulting string within GitHub Actions secrets. 

Then, in your GitHub Actions job, you can retrieve the file by decoding it. You can use this code for an Ubuntu runner:

- name: Get secret from base64 
  env: 
    KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} 
  run: | 
    echo import certificate from secrets and regenerate the file 
    echo $KEYSTORE_BASE64 | base64 -d > $RUNNER_TEMP/my_production.keystore

Related content:

Managing Environment Variables with Configu

Configu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:

Configu Orchestrator

As applications become more dynamic and distributed in microservices architectures, configurations are getting more fragmented. They are saved as raw text that is spread across multiple stores, databases, files, git repositories, and third-party tools (a typical company will have five to ten different stores).

The Configu Orchestrator, which is open-source software, is a powerful standalone tool designed to address this challenge by providing confConfigu is a configuration management platform comprised of two main components, the stand-alone Orchestrator, which is open source, and the Cloud, which is a SaaS solution:

Configu Cloud

Configu Cloud is the most innovative store purpose-built for configurations, including environment variables, secrets, and feature flags. It is built based on the Configu configuration-as-code (CaC) approach and can model configurations and wrap them with unique layers, providing collaboration capabilities, visibility into configuration workflows, and security and compliance standardization.

Unlike legacy tools, which treat configurations as unstructured data or key-value pairs, Configu is leading the way with a Configuration-as-Code approach. By modeling configurations, they are treated as first-class citizens in the developers’ code. This makes our solution more robust and reliable and also enables Configu to provide more capabilities, such as visualization, a testing framework, and security abilities.

Learn more about Configu

Related Content

Setting Environment Variables in PowerShell: A Practical Guide

React Environment Variables: Basics, Tutorial, and Best Practices

Working with Python Configuration Files: Tutorial & Best Practices

Jenkins Environment Variables: Practical Guide with Code Examples

Working with Java Environment Variables & 4 Ways to Set Variables

7 Types of Testing Environments and Best Practices for Yours

4 Ways to Set Docker Compose Environment Variables

Next.js Environment Variables: Built-In, Public, and Private

Node.js Environment Variables: Working with process.env and dotenv

Environment Variables: How to Use Them and 4 Critical Best Practices

Setting Docker Environment Variables: The Ultimate Guide

Leveraging Environment Variables in Python Programming

Try Configu for free
Painless end-to-end configuration management platform
Get Started for Free