Keywords: GitHub Actions | Branch Name | Environment Variables | Docker Images | CI/CD
Abstract: This article provides an in-depth exploration of various methods for extracting the current branch name within GitHub Actions workflows. By analyzing the characteristics of environment variables GITHUB_REF, GITHUB_HEAD_REF, and GITHUB_REF_NAME, combined with parameter expansion and conditional expressions, it offers complete solutions suitable for both push and pull_request events. The article includes detailed YAML configuration examples and practical application scenarios to help developers correctly use branch names for tagging in scenarios such as Docker image building.
Introduction
In continuous integration and continuous deployment (CI/CD) workflows, accurately obtaining the current branch name is a fundamental requirement for many automated tasks. Particularly in the GitHub Actions environment, developers frequently need to use branch names as identifiers when building Docker images, deploying applications, or running specific tests. However, the format of environment variables provided by GitHub doesn't always directly meet usage requirements, necessitating mastery of proper extraction and processing methods.
Environment Variable Analysis
GitHub Actions provides multiple environment-related variables, with key variables related to branch information including:
The GITHUB_REF variable contains the complete reference path. For workflow triggers from branches, its format is refs/heads/<branch_name>. For example, when triggering a push event on the feature-branch-1 branch, the value of GITHUB_REF is refs/heads/feature-branch-1. While this complete reference format contains comprehensive information, practical usage often requires extracting the clean branch name portion.
The GITHUB_HEAD_REF variable is specifically designed for pull_request events, directly providing the source branch name of the pull request. This variable is only available when triggered by pull_request or pull_request_target events, and its value is the clean branch name, such as feature-branch-1.
Newer versions of GitHub Actions have introduced the GITHUB_REF_NAME variable, which directly provides the branch or tag name that triggered the workflow without requiring additional processing steps. However, understanding traditional processing methods remains important for compatibility reasons.
Branch Name Extraction Methods
Depending on different usage scenarios and GitHub Actions versions, we can employ various methods to obtain clean branch names.
Parameter Expansion Method
For simple branch name extraction, Bash parameter expansion functionality can be used:
${GITHUB_REF##*/}
This method works by using the ##*/ pattern matching to remove all characters from the beginning of the string up to the last slash. For example, for refs/heads/feature-branch-1, executing ${GITHUB_REF##*/} yields feature-branch-1.
However, this approach has limitations. When branch names themselves contain slashes (such as feature/deploy), this simple string processing yields incorrect results. Therefore, methods specifically designed for GitHub reference formats are recommended.
Conditional Expression Method
To support both push and pull_request events simultaneously, conditional expressions combining multiple variables can be used:
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
The advantage of this method is that it directly utilizes GitHub's context variables without requiring additional shell processing steps. github.head_ref provides the source branch name in pull_request events, while github.ref_name provides the branch name in other events.
Complete Solution
Based on community best practices, we recommend the following complete solution that considers different event types and compatibility requirements:
- name: Extract branch name
shell: bash
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
This solution works as follows: first, it checks if the GITHUB_HEAD_REF variable is available (in pull_request events), using that value directly if available; if not available, it uses parameter expansion to remove the refs/heads/ prefix from GITHUB_REF. This approach ensures correct branch name retrieval in both push and pull_request events.
Practical Application Examples
In Docker image building scenarios, we can utilize the extracted branch name for image tagging:
- name: Push to ECR
id: ecr
uses: jwalton/gh-ecr-push@master
with:
access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
region: us-west-2
image: eng:${{ steps.extract_branch.outputs.branch }}
In this example, we use steps.extract_branch.outputs.branch to reference the branch name extracted in the previous step, ensuring Docker images are correctly tagged in formats like eng:feature-branch-1.
Complete Workflow Configuration
The following is a complete workflow configuration example demonstrating how to integrate branch name extraction functionality in practice:
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Extract branch name
shell: bash
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
- name: Checkout code
uses: actions/checkout@v3
- name: Build Docker image
run: |
docker build \
-t my-app:${{ steps.extract_branch.outputs.branch }} \
-t my-app:latest \
.
- name: Push image
run: echo "Pushing image tagged ${{ steps.extract_branch.outputs.branch }}"
Considerations and Best Practices
When using branch names, several important factors should be considered:
Branch name validity: Some systems have specific requirements for tag names. For example, Docker image tags can only contain lowercase letters, numbers, dots, hyphens, and underscores, and cannot start with a dot or hyphen. If branch names don't meet these requirements, appropriate conversion processing is necessary.
Event type differences: Different GitHub events provide different environment variables. push events use GITHUB_REF, while pull_request events should prioritize GITHUB_HEAD_REF because GITHUB_REF in pull_request points to the merge branch rather than the source branch.
Output variable scope: Output variables set via $GITHUB_OUTPUT are only available within the current job. If branch names need to be shared across multiple jobs, consider using workflow-level environment variables or artifact passing.
Community Discussion and Development
According to GitHub community discussions, many developers have expressed the need for standardized branch name environment variables. Currently, multiple different implementation approaches exist, which increases the complexity of maintaining and understanding workflows. The GitHub team is continuously improving platform functionality, with the introduction of GITHUB_REF_NAME representing an important step toward standardization.
When selecting solutions, it's recommended to prioritize using the latest official variables (such as GITHUB_REF_NAME) while providing fallback options for older versions to ensure workflow compatibility across different environments.
Conclusion
Retrieving the current branch name in GitHub Actions is a common but carefully handled task. By understanding the characteristics and applicable scenarios of different environment variables, combined with appropriate string processing techniques, we can construct robust and reliable branch name extraction solutions. The methods introduced in this article have been community-validated and can meet the requirements of most usage scenarios, providing a solid foundation for implementing automated workflows.