Mastering GitHub Actions: Working with Environment Variables
In any CI/CD pipeline, hardcoding values like database URLs, API versions, or build environments is a bad practice. Environment variables allow you to store and reuse configuration data dynamically. In GitHub Actions, understanding how to define, access, and scope these variables is essential for creating flexible and maintainable workflows.
What are Environment Variables?
Environment variables are key-value pairs used to pass configuration information into your scripts and commands. In GitHub Actions, they can be used to store everything from the name of a Java JAR file to the specific deployment region for a cloud provider.
Understanding Variable Scopes
GitHub Actions allows you to define variables at three different levels. The level at which you define a variable determines its "scope" or where it can be accessed.
Workflow Level (Global)
│
├── Job Level (Available only to specific job)
│ │
│ └── Step Level (Available only to specific step)
- Workflow Level: Defined at the root of the YAML file. Accessible by all jobs and steps in the workflow.
- Job Level: Defined within a specific job. Accessible only by the steps within that job.
- Step Level: Defined within a specific step. Accessible only by that specific step.
Defining and Using Variables
You define variables using the env keyword. To access them, you can use the env context in expressions or access them directly as environment variables in shell scripts.
Example: Java Build Configuration
In this example, we define a global variable for the Java version and a job-specific variable for the Maven build profile.
name: Java CI with Env Vars
on: [push]
env:
JAVA_VERSION: '17' # Workflow level
jobs:
build:
runs-on: ubuntu-latest
env:
BUILD_PROFILE: 'production' # Job level
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
- name: Build with Maven
run: mvn clean package -P${{ env.BUILD_PROFILE }}
env:
MAVEN_OPTS: "-Xmx2g" # Step level
Default Environment Variables
GitHub provides several built-in environment variables that are automatically available in every runner. These are useful for getting metadata about the repository or the current run.
- GITHUB_REPOSITORY: The owner and repository name (e.g., "octocat/Hello-World").
- GITHUB_SHA: The commit SHA that triggered the workflow.
- GITHUB_REF: The branch or tag ref that triggered the workflow.
- GITHUB_RUN_ID: A unique number for each workflow run.
Real-World Use Cases
1. Versioning: Using a variable to manage the version number of your application across multiple build and deployment steps.
2. Dynamic Naming: Naming build artifacts based on the current branch name or commit hash using GITHUB_REF or GITHUB_SHA.
3. Feature Toggles: Enabling or disabling specific tests or build steps based on a custom variable defined at the start of the workflow.
Common Mistakes to Avoid
- Case Sensitivity: Environment variables are case-sensitive.
MY_VARis not the same asmy_var. - Context Syntax: Forgetting to use the
${{ env.VAR_NAME }}syntax when using variables inside awithorifstatement. - Shadowing: Defining a variable at the step level with the same name as a workflow-level variable will "shadow" (overwrite) the global one for that specific step.
- Confusing Variables with Secrets: Never store passwords, API keys, or tokens in
envblocks. Use GitHub Secrets for sensitive data.
Interview Notes: Environment Variables
- Question: How do you pass a variable from one step to another?
- Answer: You can use the
GITHUB_OUTPUTfile to set an output in one step and reference it in another using thestepscontext. - Question: What is the precedence of environment variables in GitHub Actions?
- Answer: The most specific scope wins. A step-level variable overrides a job-level variable, which in turn overrides a workflow-level variable.
- Question: Can you use environment variables in the
on:trigger section? - Answer: No, environment variables are only available after the workflow run has started and the runner is initialized.
Summary
Environment variables are the backbone of dynamic GitHub Actions workflows. By mastering the workflow, job, and step scopes, you can create highly reusable CI/CD pipelines. Remember to use default variables for repository metadata and always reserve the env block for non-sensitive configuration, keeping your secrets secure in the dedicated Secrets store.
Next Topic: securing-sensitive-data-with-secrets