The orchestration of continuous integration and continuous delivery (CI/CD) pipelines within the GitHub ecosystem relies heavily on the ability of a workflow to perceive its own state and the environment in which it is executing. At the core of this capability are predefined environment variables. These variables act as the connective tissue between the GitHub event trigger, the runner's operating system, and the specific action being executed. For developers building workflows, shell scripts, or build jobs of any significant merit, leveraging these variables is not merely an option but a necessity. Without them, a workflow would be static, unable to adapt to the specific branch, commit, or user that triggered the execution.
The landscape of these variables is broader than what is typically presented in introductory documentation. While GitHub provides a standard set of default variables prefixed with GITHUB_, there is a secondary, more expansive layer of environment variables provided by the runner images themselves. Whether a developer is utilizing Ubuntu, macOS, or Windows, the runner container offers a full suite of variables that can be exploited to optimize build processes and automate complex deployment logic.
The Architecture of Default GitHub Environment Variables
GitHub establishes a specific set of variables that are injected into every runner environment, regardless of the operating system. These variables are designed to provide metadata about the workflow run, the triggering event, and the identity of the actor involved.
One critical architectural distinction is the difference between environment variables and context properties. Default environment variables are set by the GitHub platform and are available to every step in a workflow. Because they are set by the platform and not defined within the workflow YAML itself, they are not accessible through the env context. Instead, most of these variables have a corresponding context property. For example, while the environment variable GITHUB_REF is available to the shell, it can be accessed during workflow processing using the ${{ github.ref }} context property.
Immutable Nature of Default Variables
A key constraint for developers to understand is that default environment variables named GITHUB_* and RUNNER_* cannot be overwritten. This ensures that the integrity of the workflow's metadata remains intact throughout the execution lifecycle. However, there is a notable exception: the CI variable. Currently, developers can overwrite the value of CI, although GitHub does not guarantee that this capability will persist in future iterations of the platform.
The Core Default Variable Catalog
The following table provides a detailed breakdown of the 18 primary default environment variables available to any GitHub Actions workflow or shell script.
| Variable | Description |
|---|---|
| CI | Always set to true; used to detect if the script is running in a CI environment. |
| GITHUB_WORKFLOW | The name of the workflow. |
| GITHUBRUNID | A unique identifier for the specific workflow run. |
| GITHUBRUNNUMBER | A unique number for each run of a particular workflow. |
| GITHUB_ACTION | The name of the action currently running, or the id of a step. |
| GITHUB_ACTIONS | Always set to true when GitHub Actions is running the workflow. |
| GITHUB_ACTOR | The name of the person or app that initiated the workflow. |
| GITHUB_REPOSITORY | The owner and repository name (e.g., username/repository_name). |
| GITHUBEVENTNAME | The name of the event that triggered the workflow. |
| GITHUBEVENTPATH | The path to the current event payload. |
| GITHUB_WORKSPACE | The directory where the checkout action puts the repository. |
| GITHUB_SHA | The commit SHA that triggered the workflow. |
| GITHUB_REF | The branch or tag that triggered the workflow. |
| GITHUBHEADREF | The name of the head branch for a pull request. |
| GITHUBBASEREF | The name of the base branch for a pull request. |
| GITHUBSERVERURL | The URL of the GitHub server. |
| GITHUBAPIURL | The URL used to make requests to the GitHub API. |
| GITHUBGRAPHQLURL | The URL used to make requests to the GitHub GraphQL API. |
Deep Analysis of Specialized Action Variables
Beyond the general workflow variables, GitHub provides specialized variables specifically for actions to use across all runner environments. These are critical for creating reusable composite actions and maintaining portable code.
The CI Variable
The CI variable is always set to true. Its primary purpose is to allow software to behave differently when running in a headless CI environment compared to a local developer machine. For instance, a test suite might disable interactive prompts or use a specific logging format when CI is detected.
GITHUB_ACTION and Naming Conventions
The GITHUB_ACTION variable identifies the specific action or step currently executing. The value depends on the context:
- For an action, it follows the format
repo-owner/name-of-action-repo. GitHub removes special characters from this string. - When a step runs a script without a defined id, the value is
__run. - If the same script or action is invoked multiple times within a single job, GitHub appends a sequence number preceded by an underscore. For example, the first script is
__run, the second is__run_2. Similarly, ifactions/checkoutis used twice, the second instance is namedactionscheckout2.
GITHUBACTIONPATH and Repository Access
The GITHUB_ACTION_PATH variable provides the absolute path where an action is located on the runner's filesystem. This is exclusively supported in composite actions. The real-world impact of this variable is that it allows developers to avoid hardcoding file paths. By using this path, an action can change directories to its own location and access auxiliary files stored within the same repository, such as scripts or configuration files. An example path would look like /home/runner/work/_actions/repo-owner/name-of-action-repo/v1.
GITHUBACTIONREPOSITORY and GITHUB_ACTOR
The GITHUB_ACTION_REPOSITORY variable identifies the owner and repository name of the action being executed, such as actions/checkout. This differs from GITHUB_REPOSITORY, which refers to the repository where the workflow is running. Meanwhile, GITHUB_ACTOR captures the handle of the user or application that initiated the workflow, such as octocat or cansavvy.
Runner-Specific Environment Variables and OS Variance
While the GITHUB_* variables are consistent across platforms, the total number of environment variables available depends heavily on the runner image (Ubuntu, macOS, or Windows).
The Ubuntu-Latest Environment
On an ubuntu-latest image, developers have access to more than 60 additional environment variables beyond the standard 18. These variables are provided by the distribution and the pre-installed software on the image. Because they are distro-dependent, they may vary slightly compared to other operating systems.
The Windows-Latest Environment
The windows-latest container provides the most extensive list of environment variables, with approximately 120 available. These include system-level paths and SDK locations that are essential for building Windows-based applications. Examples include:
ALLUSERSPROFILE: Set toC:\ProgramDataANDROID_HOME: Set toC:\Program Files (x86)\Android\android-sdkANDROID_NDK_HOME: Set toC:\Program Files (x86)\Android\android-sdkDOTNET_MULTILEVEL_LOOKUP: May be set to0in certain configurations.
The macOS-Latest Environment
The macos-latest image provides a set of variables that differ from Ubuntu and Windows. For instance, the PATH variable is handled differently across these systems, and the specific number of available environment variables on macOS may be slightly higher or lower than those found on Ubuntu.
Practical Implementation and Variable Exploration
To fully understand the environment variables available in a specific runner, developers can write workflows designed to inspect the environment.
Manual Exploration via Shell Commands
A developer can verify the variables currently set in their environment by running a simple shell command within a workflow step. Using the env command on Linux or macOS, or set on Windows, will print all available environment variables to the logs.
User-Defined Variables vs. Default Variables
GitHub Actions distinguishes between two types of variables:
- Default Variables: These are pre-configured by GitHub (e.g.,
GITHUB_REPOSITORY). - User-Set Variables: These are defined by the developer within the workflow YAML.
User-defined variables can be set within a step using the env: keyword. The syntax involves placing the variable name on the left side of a colon and the definition on the right.
Workflow Implementation Example
To explore these variables, a developer might implement the following process:
Create a new branch for experimentation:
bash git checkout -b "env-var"Move a sample workflow file into the correct directory:
bash mv activity-1-sample-github-actions/exploring-var-and-secrets.yml .github/workflows/exploring-var-and-secrets.ymlCommit and push the changes to trigger the workflow:
bash git add .github/* git commit -m "exploring gha variables" git push --set-upstream origin env-var
Once the workflow is triggered, the developer can navigate to the pull request page and click the Details button next to the workflow run to view the logs. In these logs, they can see the output of commands such as:
bash
echo ${{ github.repository }}
This will output the username and repository name, confirming the value of the GITHUB_REPOSITORY variable.
Contextual Application of Variables
The utility of these variables becomes apparent when analyzing specific trigger scenarios.
The Role of GITHUB_REF
The GITHUB_REF variable identifies the branch or tag that triggered the workflow. For example, it might output refs/pull/1/merge. However, it is important to note that GITHUB_REF will be blank if the trigger is not related to branches or tags. A specific example of this is a workflow_dispatch event, where the variable will not contain the expected reference.
Using Variables for Filesystem Navigation
GitHub strongly recommends that actions use variables to access the filesystem rather than employing hardcoded file paths. Hardcoding paths like /home/runner/work/... creates fragile workflows that break when the runner environment is updated or changed. By utilizing variables like GITHUB_WORKSPACE or GITHUB_ACTION_PATH, the workflow remains portable and resilient across different runner versions.
Conclusion
The predefined environment variables in GitHub Actions provide a robust framework for dynamic workflow execution. By bridging the gap between the GitHub platform's metadata and the runner's operating system, these variables allow for precise control over the CI/CD pipeline. The distinction between the immutable GITHUB_* variables and the user-definable env variables ensures a stable yet flexible environment. While the standard 18 variables provide the baseline for most needs, the deeper pool of OS-specific variables—particularly the extensive list on windows-latest—enables developers to handle complex SDK and system configurations without manual setup. Mastering the use of these variables, and understanding the nuance between environment variables and context properties, is essential for any developer aiming to create professional, scalable, and maintainable automation on GitHub.