
Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: September 27, 2024
When developing automated workflows in GitHub Actions, determining the current branch is often essential. Whether automating deployments or running tests, accessing the branch name dynamically can be key to ensuring workflows behave as expected. This is particularly important in multi-branch workflows where different branches represent different stages in the development lifecycle, such as feature branches, staging, and production.
In this tutorial, we’ll explore how to get the current branch name in GitHub Actions. We’ll cover the built-in GitHub context that provides branch information and demonstrate how to use it effectively in various workflow scenarios.
GitHub Actions provide built-in contexts that offer valuable information during workflow execution, such as details about the environment, event triggers, and job states.
The most frequently used contexts include:
Each context plays a significant role in making workflows adaptable, but to identify the current branch in GitHub Actions, the github context is the most relevant.
Let’s discuss more about the github context in the next section.
The github context holds metadata about the repository and event that triggered the workflow. It’s automatically available in all workflows and is crucial for accessing branch or tag information.
The key property for branch identification is github.ref, which stores the branch or tag reference for the event. This allows workflows to behave differently based on the branch.
The github.ref property provides the full reference string, starting with refs/heads/ followed by the branch name. For example, on a push to the main branch, github.ref contains:
refs/heads/main
To extract the branch name, we simply parse the substring after refs/heads/.
Identifying the current branch in GitHub Actions is crucial for customizing workflow behavior, such as deploying from main or running specific tests on feature branches.
For push events, we retrieve the branch name through the github.ref property. For pull request events, we use github.head_ref to get the source branch.
While github.ref provides the branch reference for push events, its format changes for pull requests. In push events, github.ref points directly to the branch (for example, refs/heads/main).
For pull requests, it refers to the target branch with a pull request reference. To get the source branch, we use github.head_ref, which returns the name of the branch where the pull request originated.
To extract the branch name, we remove the refs/heads/ prefix from github.ref using string manipulation. When accessed in shell commands, GitHub converts github.ref to an environment variable, GITHUB_REF, enabling us to extract the branch name with:
${GITHUB_REF##*/}
This removes the refs/heads/ prefix, leaving only the branch name. The automatic conversion of context properties like github.ref into environment variables makes them accessible in shell scripts without additional setup.
Now that we understand the differences between github.ref and github.head_ref in push and pull request events, let’s look at an example of retrieving the correct branch name for each.
To do this, we’ll write a GitHub Actions workflow that retrieves and prints the branch name on every push event.
Firstly, let’s create the folder structure:
$ mkdir get-current-branch-in-github-actions && cd get-current-branch-in-github-actions
$ mkdir -p .github/workflows
Inside the .github/workflows folder, let’s create a new file named push-branch-name.yml:
$ touch .github/workflows/push-branch-name.yml
Now, let’s write the workflow code that prints the branch name on every push event:
name: Print Branch Name on Push
on:
push:
branches:
- "*"
jobs:
print-branch-name:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Print branch name
run: |
echo "Current branch: ${GITHUB_REF##*/}"
This workflow runs on any push event to the repository, as specified by the on: push section, ensuring that it runs regardless of the branch. The actions/checkout@v3 action checks out the repository’s code, a common step required for most workflows.
To display the branch name, we used the expression ${GITHUB_REF##*/}. This string manipulation removes the refs/heads/ prefix from the GITHUB_REF variable, leaving only the branch name. The workflow then prints the branch name in the logs.
Now, we need to verify the workflow for push events. Firstly, let’s create a new repository and push it to GitHub:
$ git init
$ git add .
$ git commit -m "Add workflow to print branch name on push"
$ git branch -M main
$ git remote add origin <your-github-repo-url>
$ git push -u origin main
With the workflow pushed, let’s navigate to the Actions tab in the GitHub repository. The workflow automatically triggers when the push event occurs.
From the Actions tab, let’s locate the latest workflow run triggered by the push and open it to view the details:
We can verify that the logs display the branch name as expected. This confirms that the ${GITHUB_REF##*/} expression successfully extracted the branch name by removing the refs/heads/ prefix.
Let’s now write a workflow that retrieves and prints the branch name when a pull request opens or updates. For pull request events, we use github.head_ref to access the source branch, as opposed to push events where github.ref references the branch being pushed.
Firstly, let’s create a new workflow file named pull-request-branch-name.yml, in the .github/workflows directory:
touch .github/workflows/pull-request-branch-name.yml
Then, define the workflow to run on pull request events:
name: Print Branch Name on Pull Request
on:
pull_request:
branches:
- "*"
jobs:
print-branch-name:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Print source branch name
run: |
echo "Source branch: ${{ github.head_ref }}"
shell: bash
This workflow listens for pull request events, as defined by the on: pull_request trigger. When a pull request is opened or updated, the workflow runs and retrieves the source branch of the pull request using ${{ github.head_ref }}, which directly references the branch name where the pull request originated.
Next, let’s create and checkout to a new branch and push it to GitHub:
$ git checkout -b pull-request-branch-name
$ git add .
$ git commit -m "Add workflow to print branch name on pull request"
$ git push origin pull-request-branch-name
After pushing to GitHub, we can create a pull request by navigating to the Pull requests tab in the GitHub repository. Here, we click on the New pull request button. From the compare dropdown, let’s select the pull-request-branch-name as the source branch and the main branch as the target branch:
Once the pull request is created, the workflow triggers automatically based on the on: pull_request event. To verify if the workflow is running correctly, let’s navigate to the Actions tab in the repository. Find the workflow triggered by the pull request and inspect the logs:
Here, we can now see the pull request source branch name, pull-request-branch-name. This confirms that the workflow functions as expected, and the source branch name is being retrieved and printed using ${{ github.head_ref }}.
In addition to retrieving the branch name for push or pull request events separately, we can streamline the workflow to handle both scenarios within the same configuration. This allows us to display the branch name regardless of whether the workflow was triggered by a push or a pull request event. The workflow adapts based on the event type, ensuring we retrieve the correct branch name using either GITHUB_REF for push events or github.head_ref for pull request events.
Here’s the code that handles both push and pull request events:
name: Print Branch Name On Push and Pull Requests
on:
push:
branches:
- "*"
pull_request:
branches:
- "*"
jobs:
print-branch-name:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Get branch name
id: get-branch-name
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "BRANCH_NAME=${{ github.head_ref }}" >> $GITHUB_OUTPUT
else
echo "BRANCH_NAME=${GITHUB_REF##*/}" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Print branch name
run: |
echo "Branch name: ${{ steps.get-branch-name.outputs.BRANCH_NAME }}"
shell: bash
This workflow triggers on both push and pull request events, as defined by the on: push and on: pull_request sections.
The key step here is the Get branch name section, which checks the type of event that triggered the workflow using github.event_name. If the event is a pull request, the workflow retrieves the source branch using github.head_ref. Otherwise, it uses string manipulation to extract the branch name from GITHUB_REF for push events.
The resulting branch name is stored in a variable BRANCH_NAME, which is then printed to the workflow logs in the final step. We can verify this by checking out to a new branch, just like in the previous section, and pushing it to GitHub:
$ git checkout -b push-pull-request-branch-name
$ git add .
$ git commit -m "add get current branch on push and pull requests event"
$ git push origin push-pull-request-branch-name
Once the push completes, we can create a pull request. Then, GitHub Actions will trigger the workflow for both the push and pull request events, displaying the branch name in the logs.
To easily check the logs for each event, we can filter the workflows by the event type:
We can verify that the correct branch name was printed for both cases, ensuring that the logic worked for each type of event.
In this article, we learned how to retrieve the current branch name in GitHub Actions. We began by understanding GitHub’s built-in contexts, focusing on github.ref and github.head_ref, and how they provide information about branches during push and pull request events. Then, we proceeded to practical examples of setting up workflows to display the branch name.
Correctly identifying the branch in different events is crucial for ensuring that workflows behave as expected, especially in multi-branch environments. By understanding how to use github.ref and github.head_ref, we can better control our workflows and streamline development processes across different branches. The complete code for this article is available over on GitHub.