Examine environment variables
Environment variables are essential for creating flexible and maintainable GitHub Actions workflows. They allow you to configure behavior, pass data between steps, and adapt workflows to different environments without hardcoding values.
Understanding environment variables in GitHub Actions
Environment variables provide a way to store and access configuration data within your workflows. They can be set at different scopes and used throughout your automation pipeline for consistent and secure configuration management.
Variable scopes and hierarchy
GitHub Actions supports environment variables at multiple levels:
Workflow level: Available to all jobs in the workflow
Job level: Available to all steps in a specific job
Step level: Available only to that specific step
name: Multi-level Environment Variables
# Workflow-level variables
env:
NODE_VERSION: "20"
BUILD_CONFIGURATION: "Release"
jobs:
build:
runs-on: ubuntu-latest
# Job-level variables
env:
DATABASE_NAME: "production_db"
API_TIMEOUT: "30000"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Run tests with custom config
run: npm test
# Step-level variables
env:
TEST_ENVIRONMENT: "ci"
LOG_LEVEL: "debug"
Built-in GitHub environment variables
GitHub automatically provides numerous environment variables with information about the workflow context:
Essential built-in variables
| Variable | Description | Example Value |
|---|---|---|
GITHUB_WORKFLOW |
Name of the workflow | "CI Pipeline" |
GITHUB_ACTION |
Unique identifier of the action | "__actions_checkout" |
GITHUB_REPOSITORY |
Repository name (owner/repo) | "microsoft/vscode" |
GITHUB_REF |
Branch or tag reference | "refs/heads/main" |
GITHUB_SHA |
Commit SHA that triggered the workflow | "ffac537e6cbb..." |
GITHUB_ACTOR |
Username of the user who triggered the workflow | "octocat" |
GITHUB_EVENT_NAME |
Event that triggered the workflow | "push" |
RUNNER_OS |
Operating system of the runner | "Linux" |
Advanced built-in variables
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Display workflow context
run: |
echo "Workflow: $GITHUB_WORKFLOW"
echo "Repository: $GITHUB_REPOSITORY"
echo "Branch: ${GITHUB_REF#refs/heads/}"
echo "Commit: $GITHUB_SHA"
echo "Actor: $GITHUB_ACTOR"
echo "Event: $GITHUB_EVENT_NAME"
echo "Runner OS: $RUNNER_OS"
Important naming rules:
- Built-in variables use the
GITHUB_prefix - You cannot create custom variables with the
GITHUB_prefix - Variable names are case-sensitive in most contexts
Practical environment variable patterns
Configuration management
name: Environment-specific Deployment
env:
# Global configuration
APP_NAME: "my-awesome-app"
DOCKER_REGISTRY: "ghcr.io"
jobs:
deploy-staging:
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
env:
ENVIRONMENT: "staging"
API_URL: "https://api.staging.example.com"
DATABASE_TIER: "basic"
steps:
- name: Deploy to staging
run: |
echo "Deploying $APP_NAME to $ENVIRONMENT"
echo "API URL: $API_URL"
docker build -t $DOCKER_REGISTRY/$APP_NAME:$GITHUB_SHA .
deploy-production:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
env:
ENVIRONMENT: "production"
API_URL: "https://api.example.com"
DATABASE_TIER: "premium"
steps:
- name: Deploy to production
run: |
echo "Deploying $APP_NAME to $ENVIRONMENT"
echo "API URL: $API_URL"
docker build -t $DOCKER_REGISTRY/$APP_NAME:latest .
Dynamic variable creation
steps:
- name: Generate build metadata
id: metadata
run: |
BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
BUILD_NUMBER=$GITHUB_RUN_NUMBER
VERSION_TAG=${GITHUB_REF#refs/tags/}
echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV
echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV
echo "VERSION_TAG=$VERSION_TAG" >> $GITHUB_ENV
- name: Use generated variables
run: |
echo "Build Date: $BUILD_DATE"
echo "Build Number: $BUILD_NUMBER"
echo "Version: $VERSION_TAG"
Multi-platform configuration
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: ubuntu-latest
BUILD_COMMAND: "make build-linux"
PACKAGE_EXT: ".deb"
- os: windows-latest
BUILD_COMMAND: "msbuild /p:Configuration=Release"
PACKAGE_EXT: ".msi"
- os: macos-latest
BUILD_COMMAND: "xcodebuild -configuration Release"
PACKAGE_EXT: ".dmg"
runs-on: ${{ matrix.os }}
env:
BUILD_COMMAND: ${{ matrix.BUILD_COMMAND }}
PACKAGE_EXT: ${{ matrix.PACKAGE_EXT }}
steps:
- name: Build application
run: ${{ env.BUILD_COMMAND }}
Security best practices for environment variables
Sensitive data handling
# DON'T: Store secrets in plain environment variables
env:
DATABASE_PASSWORD: 'super-secret-password' # Visible in logs!
# DO: Use GitHub Secrets for sensitive data
env:
DATABASE_HOST: 'db.example.com'
DATABASE_PORT: '5432'
DATABASE_USER: 'app_user'
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }} # Secure!
Environment variable validation
steps:
- name: Validate required environment variables
run: |
required_vars=("API_URL" "DATABASE_HOST" "ENVIRONMENT")
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
echo "ERROR: Required environment variable $var is not set"
exit 1
else
echo "OK: $var is set"
fi
done
Advanced techniques
Conditional environment variables
steps:
- name: Set environment-specific variables
run: |
if [ "$GITHUB_REF" = "refs/heads/main" ]; then
echo "LOG_LEVEL=info" >> $GITHUB_ENV
echo "CACHE_TTL=3600" >> $GITHUB_ENV
elif [ "$GITHUB_REF" = "refs/heads/develop" ]; then
echo "LOG_LEVEL=debug" >> $GITHUB_ENV
echo "CACHE_TTL=300" >> $GITHUB_ENV
else
echo "LOG_LEVEL=warn" >> $GITHUB_ENV
echo "CACHE_TTL=60" >> $GITHUB_ENV
fi
Environment variable templating
env:
APP_VERSION: ${{ github.ref_name }}
BUILD_ID: ${{ github.run_number }}
FULL_VERSION: ${{ github.ref_name }}-build.${{ github.run_number }}
CONTAINER_TAG: ${{ github.repository }}:${{ github.ref_name }}
Environment variables are a powerful tool for creating flexible, maintainable, and secure GitHub Actions workflows. Use them strategically to avoid hardcoded values and enable easy configuration management across different environments.
For complete documentation on environment variables, see Environment variables in GitHub Actions.