GitHub Actions Environment Variable Ecosystem

The orchestration of continuous integration and continuous delivery (CI/CD) within GitHub Actions relies heavily on the fluid exchange of data between the runner environment and the workflow logic. At the core of this exchange are environment variables—dynamic values that provide essential context about the current execution state, the trigger event, and the host operating system. For a developer to build a workflow, shell script, or build job of any significant merit, it is imperative to move beyond basic configurations and leverage the full spectrum of available variables. These variables act as the nervous system of the automation process, allowing scripts to adapt their behavior based on whether they are running on a Linux, macOS, or Windows runner, and providing the necessary metadata to interact with the GitHub API and the filesystem without relying on fragile, hardcoded paths.

Taxonomy of GitHub Actions Variables

The environment in which a GitHub Action executes is not a monolithic entity but a layered construct. The variables available to a developer are categorized by their origin and their scope, ranging from global defaults set by the GitHub platform to system-specific variables inherent to the runner's operating system.

Default GitHub Platform Variables

GitHub provides a set of 18 default environment variables that are automatically injected into every workflow run. These variables are primarily prefixed with the string GITHUB and are designed to provide universal metadata regardless of the runner's OS.

  • CI
  • GITHUB_WORKFLOW
  • GITHUBRUNID
  • GITHUBRUNNUMBER
  • GITHUB_ACTION
  • GITHUB_ACTIONS
  • GITHUB_ACTOR
  • GITHUB_REPOSITORY
  • GITHUBEVENTNAME
  • GITHUBEVENTPATH
  • GITHUB_WORKSPACE
  • GITHUB_SHA
  • GITHUB_REF
  • GITHUBHEADREF
  • GITHUBBASEREF
  • GITHUBSERVERURL
  • GITHUBAPIURL
  • GITHUBGRAPHQLURL

These default variables are critical because they allow for conditional logic within a script. For instance, the CI and GITHUB_ACTIONS variables are specifically intended to help developers differentiate between a local execution environment and the GitHub-hosted runner, ensuring that certain tests or deployment steps only trigger within the cloud infrastructure.

OS-Specific and Image-Dependent Variables

While the 18 default variables are constant, the total number of available variables expands significantly based on the runner image. If a developer utilizes the ubuntu-latest image, they gain access to over 60 additional environment variables. These are not defined by GitHub's workflow engine but are instead "standard issue" variables provided by the distribution of the operating system.

The availability of these variables fluctuates across different platforms. For example, macos-latest may provide a different set of environment variables compared to ubuntu-latest. On windows-latest, the environment is even more expansive, with the reference data indicating a listing of approximately 120 variables. A primary example of these OS-specific variables is the PATH variable on windows-latest, which is essential for the shell to locate executable binaries.

Detailed Variable Analysis and Functional Impact

To understand the utility of these variables, one must examine the specific impact of the most critical keys and how they interact with the workflow context.

Variable Detailed Description Functional Impact
CI Always set to true Allows scripts to detect they are running in a CI environment to modify output or skip interactive prompts.
GITHUB_ACTION The name of the current action or step ID. Returns __run for scripts without IDs. Enables logging and tracking of which specific step is executing within a complex job.
GITHUBACTIONPATH The filesystem path where a composite action is located. Critical for composite actions to access local files within their own repository using relative paths.
GITHUBACTIONREPOSITORY The owner and repository name of the action being executed. Used for auditing and ensuring the correct version of a third-party action is being utilized.
GITHUB_ACTIONS Always set to true when running on GitHub. Acts as a primary flag for conditional execution logic within shell scripts.
GITHUB_ACTOR The username of the person or app that triggered the workflow. Used for notifications or for restricting certain actions to specific users.

The Intersection of Environment Variables and Context Properties

There is a distinct architectural difference between an environment variable and a context property in GitHub Actions. Default environment variables are set by GitHub and are available to every step in a workflow. However, because they are not defined within the workflow YAML itself, they cannot be accessed via the env context.

Instead, GitHub provides corresponding context properties. For example, while the environment variable GITHUB_REF is available to a shell script, the same information can be accessed during the workflow processing phase using the ${{ github.ref }} context property. This distinction is vital for developers when deciding whether to access data via a shell command or via the GitHub Actions expression syntax.

Immutability and Overwriting Constraints

The GitHub environment enforces strict rules regarding which variables can be modified. This ensures that the core telemetry and identification of a run remain consistent and untampered with.

  • GITHUB_* variables: These are immutable. Developers cannot overwrite the value of any default variable starting with the GITHUB_ prefix.
  • RUNNER_* variables: These are also immutable and cannot be overwritten.
  • CI variable: Currently, the CI variable can be overwritten. However, this is not a guaranteed feature and may be restricted in future updates.

This immutability prevents accidental corruption of the workflow's state and ensures that the GITHUB_RUN_ID or GITHUB_SHA always points to the actual execution context, which is essential for debugging and traceability.

Advanced Inspection Techniques for Runner Environments

Because the full list of available variables changes based on the runner image and the specific version of the OS, developers often need to inspect the environment in real-time. The most effective way to do this is by invoking the env command within a shell.

To comprehensively map the environment of different runners, a developer can implement a specialized workflow that targets each supported OS. The following architectural approach is recommended:

  1. Define a YAML file triggered on a push to the main or master branch.
  2. Create three distinct jobs: one for ubuntu-latest, one for windows-latest, and one for macos-latest.
  3. In each job, execute a single step that runs the env command.

This process forces the container to print every available environment variable to the console, allowing the developer to verify the exact strings available for use in their scripts.

Implementation Example for Environment Discovery

```yaml
name: Publish GitHub Actions Artifacts Example
on:
push:
branches: [ main ]

jobs:
github-actions-environment-variables-ubuntu:
runs-on: ubuntu-latest
steps:
- name: List of the GitHub Actions environment variables on Windows
run: env

github-actions-environment-variables-windows:
runs-on: windows-latest
steps:
- name: Ubuntu GitHub Actions environment variables List
run: env

github-actions-environment-variables-macos:
runs-on: macos-latest
steps:
- name: MacOs List of GitHub Actions environment variables
run: env
```

In the case of the windows-latest environment, this inspection would reveal a vast array of variables, including those related to the Android SDK, such as:

  • ALLUSERSPROFILE which maps to C:\ProgramData
  • ANDROID_HOME which maps to C:\Program Files (x86)\Android\android-sdk
  • ANDROID_NDK_HOME which maps to C:\Program Files (x86)\Android\android-sdk

Variables in Composite Actions and Repository Settings

Beyond the default environment variables, GitHub allows for the definition of custom variables via the organization or repository settings (/settings/variables/actions). These are accessed using the vars context.

Accessing Repository Variables

Custom variables defined in the settings are intended to provide a way to store non-sensitive configuration data that can be shared across multiple workflows. However, there are known complexities regarding their visibility:

  • Contextual Access: Custom variables are accessed via ${{ vars.VARIABLE_NAME }}.
  • Composite Action Limitations: There have been reports in the community regarding the lack of direct reference for ${{ vars }} within composite actions. When used in a composite action, these variables may not appear as direct references in the runner environment or inputs, leading to situations where the value is reported as not found.

Best Practices for Filesystem Interaction

GitHub strongly advises against the use of hardcoded file paths within workflows. Because the directory structure can vary between different runner versions and operating systems, developers should always utilize the provided environment variables to access the filesystem. Using GITHUB_WORKSPACE ensures that the action is operating within the correct directory, regardless of whether the runner is a Linux container or a Windows virtual machine.

Comprehensive Analysis of Variable Integration

The synergy between default environment variables and user-defined variables creates a robust framework for automation. By utilizing GITHUB_WORKSPACE, a developer ensures that their scripts are portable. If a script is written to expect a specific absolute path on Ubuntu, it will inevitably fail on Windows. By relying on the environment variables provided by GitHub, the workflow becomes agnostic to the underlying infrastructure.

The impact of using GITHUB_ACTION and GITHUB_ACTION_PATH is most evident in the creation of reusable composite actions. These allow developers to bundle multiple steps into a single action. Without GITHUB_ACTION_PATH, a composite action would have no reliable way to locate the auxiliary scripts or configuration files stored within its own repository, as the checkout action places the code in a dynamic location on the runner's disk.

The use of GITHUB_SHA and GITHUB_REF allows for the creation of sophisticated deployment pipelines. For example, a workflow can be configured to only deploy to a production environment if GITHUB_REF equals refs/heads/main. This prevents accidental deployments from feature branches, providing a critical layer of safety in the CI/CD lifecycle.

Sources

  1. The Server Side
  2. GitHub Documentation
  3. GitHub Community Discussions

Related Posts