Baeldung Pro – Ops – NPI EA (cat = Baeldung on Ops)
announcement - icon

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.

Partner – Orkes – NPI EA (cat=Kubernetes)
announcement - icon

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

1. Overview

GitHub Actions is one of the most powerful CI/CD platforms, allowing us to automate workflows for GitHub repositories. When writing these workflows, one common requirement is to access the commit message for the commit that triggered the workflow. Using this information, we can solve various use cases, such as automating changelog generation, enforcing commit standards in a repository, and so on.

In this tutorial, we’ll explore multiple ways to get the commit message in GitHub Actions.

2. Using the github.event Context

In this section, we’ll learn how to use the information available within the github.event context to get the commit message for the pull_request and push events.

2.1. With pull_request Event

Let’s start by adding the workflow definition to the commit-message-pr.yml file in our GitHub repository:

$ cat .github/workflows/commit-message-pr.yml
name: Get Commit Message from Event Object

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  extract-commit-message:
    runs-on: ubuntu-latest
    steps:
      - name: Get commit message (Pull Request)
        if: github.event_name == 'pull_request'
        run: |
          echo "Commit Title: ${{ github.event.pull_request.title }}"
          echo "Commit Body: ${{ github.event.pull_request.body }}"

We’ve defined the extract-commit-message job to get executed only for pull_request events. Interestingly, we’ve used the context information, github.event.pull_request.title and github.event.pull_request.body to get the commit title and commit body, respectively.

Now, let’s raise a pull request from our branch with the changes to the main branch:

Sample Pull Request

It’s important to note that GitHub automatically picked the commit message as the PR title. However, GitHub exhibits this behavior only when there is a single commit in the changes. As a result, this approach to getting the commit message is limited to pull requests with a single commit.

Lastly, we can check the logs for the workflow run triggered by the pull_request event:

Pull Request Event - Get Commit Message

Great! It worked as expected.

2.2. With push Event

Let’s add the workflow definition to the commit-message-push.yml file of our GitHub repository:

$ cat .github/workflows/commit-message-push.yml
name: Get Commit Message from Event Object

on:
  push:

jobs:
  extract-commit-message:
    runs-on: ubuntu-latest
    steps:
      - name: Get commit message (Push)
        if: github.event_name == 'push'
        run: |
          echo "Commit Message: ${{ github.event.head_commit.message }}"

The extract-commit-message job in our workflow executes only for push events. Moreover, we used the github.event.head_commit.message context information to get the commit message.

Now, after pushing a commit, let’s check the logs for a live run of the workflow:

Push Event - Get Commit Message Using Context

Great! Our job was executed successfully, and the commit message for the latest commit is shown.

3. Using the git Command

In this section, let’s learn how to use the git command to solve our use case of getting the commit message in GitHub Actions.

3.1. With pull_request Event

We can start by adding the workflow definition in the commit-message-pr-git-cmd.yml file of the repository:

$ cat .github/workflows/commit-message-pr-git-cmd.yml
name: Get commit message using git log command

on:
  pull_request:

jobs:
  extract-commit-message:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Get commit message (Pull Request)
        if: github.event_name == 'pull_request'
        run: |
          pr_num=${{ github.event.pull_request.number }}
          git fetch origin refs/pull/${pr_num}/head:refs/remotes/origin/pull/${pr_num}/head
          commit_title=$(git log -1 --pretty=format:"%s" origin/pull/${pr_num}/head)
          commit_body=$(git log -1 --pretty=format:"%b" origin/pull/${pr_num}/head)
          echo "Commit Title: $commit_title"
          echo "Commit Body: $commit_body"

Firstly, we used the predefined actions/checkout action in the GitHub action to checkout our repository. Then, we determined the pull request number using the github.event.pull_request.number context and used it to fetch the head of the branch with the changes. Lastly, we used the git log command to get the title and body of the commit message.

Now, let’s see the logs of our workflow run on raising a pull request to confirm that the workflow shows the information about the commit message:

Pull Request Event - Get commit message using git log

Fantastic! It looks like we nailed this one.

3.2. With push Event

For this approach, let’s go ahead and define a new workflow in the commit-message-push-git-cmd.yml file:

$ cat .github/workflows/commit-message-push-git-cmd.yml
name: Get commit message using git log command
on:
  push:

jobs:
  extract-commit-message:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Get commit message (Push)
        if: github.event_name == 'push'
        run: |
          commit_title=$(git log -1 --pretty=format:"%s")
          commit_body=$(git log -1 --pretty=format:"%b")
          echo "Commit Title: $commit_title"
          echo "Commit Body: $commit_body"

We added a check for the event_name to execute this flow only for push events. We then used the actions/checkout action to checkout the repository. Later on, we used the git log command to get the commit title and body.

Now, let’s push our code changes and see our workflow run in action:

Push Event - Get commit message using git log

Great! The extract-commit-message job executed successfully and shows the correct output.

4. Using the GitHub API

In this section, we’ll solve the use case by leveraging the octokit/request-action GitHub action to make API calls to GitHub from within GitHub Actions.

4.1. With pull_request Event

Let’s go ahead and define our workflow in the commit-message-pr-api.yml file in our repository:

$ cat .github/workflows/commit-message-pr-api.yml
name: Get commit message using GitHub API

on:
  pull_request:

jobs:
  extract-commit-message:
    runs-on: ubuntu-latest
    steps:
      - name: Fetch commit messages from PR
        id: get_commits
        uses: octokit/[email protected]
        with:
          route: GET /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Get latest commit message
        run: |
          echo "Commit message:"
          echo '${{ steps.get_commits.outputs.data }}' | jq -r '.[-1].commit.message'

We used the commits API endpoint to get the list of commits in the pull request. Later, we used the jq command to extract the commit message of the latest commit in the JSON array consisting of all the commits.

Now, we can raise a pull request and check our workflow in action:

Pull Request - Get commit message using GitHub API

Excellent! Our job was executed successfully, and we can see the commit message as expected.

4.2. With push Event

Similar to our earlier approach, we can define the new workflow in the commit-message-push-api.yml file:

$ cat .github/workflows/commit-message-push-api.yml
name: Get commit message using GitHub API

on:
  push:

jobs:
  extract-commit-message:
    runs-on: ubuntu-latest
    steps:
      - name: Fetch commit messages
        id: get_commits
        uses: octokit/[email protected]
        with:
          route: GET /repos/${{ github.repository }}/compare/${{ github.event.before }}...${{ github.sha }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Get latest commit message
        env:
          DATA: ${{ steps.get_commits.outputs.data }}
        run: |
          echo "Commit message:"
          echo "$DATA" | jq -r '.commits[-1].commit.message'

In this scenario, we used the compare API to get the list of commits after the push event using the commit SHAs available in the github.event.before and github.sha context variables. Further, we defined an environment variable, DATA, to hold the output from the get_commits step. Later, we extracted the commit message value of the latest commit from the JSON array in the DATA variable.

Moving on, let’s push our code changes and see a live run of the workflow:

Push Event - Get commit message using GitHub API

Brilliant! We got this one right, too.

5. Conclusion

In this tutorial, we learned how to get the commit message in GitHub Actions. We started by using the github.event context for a simple scenario, especially for the pull_request event containing a single commit. Later, we explored other advanced techniques, such as the git command and the GitHub APIs, to get the commit message more generically.