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 offers a powerful CI/CD platform tightly integrated with the GitHub ecosystem. When working with pull requests (PRs), we often need metadata like the PR number, PR title, commit SHA, and so on. Among these, the PR title is particularly useful when triggering based on the title patterns.

In this article, we’ll explore how to retrieve the title of a pull request in GitHub actions using built-in GitHub context, the GitHub CLI, and the GitHub API endpoints.

2. Using the GitHub Context

When pull_request event triggers our workflow, GitHub automatically includes the PR data in the github context.

Let’s add our workflow in the show-pr-title.yml file to get the PR title:

$ cat .github/workflows/show-pr-title.yml
name: "Show PR Title via github context"

on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
      - closed
      - assigned
      - unassigned
      - labeled
      - unlabeled
      - locked
      - unlocked
      - review_requested
      - review_request_removed
      - ready_for_review
      - converted_to_draft

jobs:
  show-title:
    runs-on: ubuntu-latest
    steps:
      - name: Display PR title
        run: 'echo "PR title: ${{ github.event.pull_request.title }}"'

We’ve added the trigger for the workflow as a pull_request event. Further, we specified a comprehensive list of eligible types, such as opened, edited, and so on, explicitly for this tutorial.

It’s important to note that this approach is most optimized when we want to get the title for pull_request events. However, it won’t work for other triggers, such as push, workflow_dispatch, and so on.

3. Using the gh CLI

In this section, we’ll learn how to use the gh CLI commands to get the title of a pull request.

3.1. With the Pull Request Number

When our workflow trigger is a pull_request event, we can make use of the pull request number with the gh pr view command to get the pull request title.

Let’s check out our workflow definition:

$ cat .github/workflows/show-pr-title.yml
name: "PR Title via gh CLI"

on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
      - closed
      - assigned
      - unassigned
      - labeled
      - unlabeled
      - locked
      - unlocked
      - review_requested
      - review_request_removed
      - ready_for_review
      - converted_to_draft

jobs:
  get-title:
    runs-on: ubuntu-latest
    steps:
      - name: Show PR Title via gh pr view command
        if: github.event_name == 'pull_request'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "This is a PR event."
          title=$(gh pr view ${{ github.event.pull_request.number }} \
            --repo ${{ github.repository }} \
            --json title -q .title)
          echo "PR title: $title"

In our workflow, we fetched the pull request number from the github.event context, however, it could easily be replaced by a different source.

3.2. With the Branch Name

GitHub allows a single open PR per branch, so we can also use the branch name with the gh pr list command to get the pull request title.

Let’s see the workflow definition for this approach:

$ cat .github/workflows/show-pr-title.yml
name: "PR Title via gh CLI"

on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
      - closed
      - assigned
      - unassigned
      - labeled
      - unlabeled
      - locked
      - unlocked
      - review_requested
      - review_request_removed
      - ready_for_review
      - converted_to_draft
  push:
  workflow_dispatch:

jobs:
  get-title:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Try to get PR title from current branch (push or manual dispatch)
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          if [[ "${{ github.event_name }}" == "pull_request" ]]; then
            branch="${{ github.head_ref }}"
          else
            branch="${GITHUB_REF#refs/heads/}"
          fi
          pr_json=$(gh pr list --head "$branch" --state open --repo "${{ github.repository }}" --json number,title --jq '.[0]')
          if [[ -n "$pr_json" ]]; then
            pr_title=$(echo "$pr_json" | jq -r '.title')
            pr_number=$(echo "$pr_json" | jq -r '.number')
            echo "Found PR #$pr_number with title: $pr_title"
          else
            echo "No open PR found for branch: $branch"
          fi

In case of a pull_request event, we can get the branch name from the ${{ github.head_ref  }} context, otherwise we can extract it from the $GITHUB_REF variable. Further, we used the gh pr list command to get the title for the open pull request.

It’s important to note that we can use this approach for pull_request, push, or workflow_dispatch events.

4. Using the GitHub REST API

For a more portable solution, we can use the curl command to fetch the pull request title using the GitHub REST API.

Let’s write a workflow that uses the /pulls REST API endpoint to get the PR title:

$ cat .github/workflows/show-pr-title.yml
name: "Fetch PR Title via REST API"

on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
      - closed
      - assigned
      - unassigned
      - labeled
      - unlabeled
      - locked
      - unlocked
      - review_requested
      - review_request_removed
      - ready_for_review
      - converted_to_draft
  push:
  workflow_dispatch:

jobs:
  get-title:
    runs-on: ubuntu-latest
    steps:
      - name: Retrieve title for current branch
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          branch="${{ github.ref_name }}"
          api_url="https://api.github.com/repos/${{ github.repository }}/pulls?head=${{ github.repository_owner }}:$branch&state=open"
          title=$(curl -s -H "Authorization: token $GITHUB_TOKEN" "$api_url" | jq -r '.[0].title')
          echo "PR title: $title"

We retrieved the branch name from the github context and set the state query parameter to open, to list only the open pull requests.

5. Using the GitHub GraphQL API

In scenarios where we need more information than just the pull request title, we can prefer to use the GraphQL API for better performance. In this section, we’ll create a multi-step workflow to retrieve the pull request title using the GraphQL API.

First, let’s add the first step to our workflow to extract the pull request number:

$ cat .github/workflows/show-pr-title.yml
name: Get PR Title via GraphQL

on:
  pull_request:
    types:
      - opened
      - edited
      - reopened
      - synchronize
  push:
  workflow_dispatch:

jobs:
  fetch-pr-title:
    runs-on: ubuntu-latest
    steps:
      - name: Determine PR number
        id: pr-info
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            echo "pr_number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
          else
            echo "Trying to find PR from commit SHA..."
            PR_URL=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" 
              -H "Accept: application/vnd.github.groot-preview+json" 
              https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }}/pulls 
              | jq -r '.[0].url')

            if [ "$PR_URL" = "null" ] || [ -z "$PR_URL" ]; then
              echo "No PR associated with commit."
              echo "pr_number=" >> "$GITHUB_OUTPUT"
              exit 0
            fi

            PR_NUMBER=$(basename "$PR_URL")
            echo "Found PR #$PR_NUMBER"
            echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
          fi

For a pull_request event, we obtained the pull request number from the github.event context, whereas for other event types, we used the commit SHA available in the github context.

Next, let’s add a step to the workflow that makes a call to the GraphQL endpoint to query for the pull request title using the pull request number:

- name: Get PR title via GraphQL
  id: pr
  if: steps.pr-info.outputs.pr_number != ''
  run: |
    OWNER="${{ github.repository_owner }}"
    REPO="${{ github.event.repository.name }}"
    PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}"

    QUERY=$(jq -n --arg owner "$OWNER" --arg repo "$REPO" --argjson number "$PR_NUMBER" 
      '{
        query: "query($owner: String!, $repo: String!, $number: Int!) {
          repository(owner: $owner, name: $repo) {
            pullRequest(number: $number) {
              title
            }
          }
        }",
        variables: {
          owner: $owner,
          repo: $repo,
          number: $number
        }
      }')
    RESPONSE=$(curl -s -X POST https://api.github.com/graphql 
      -H "Authorization: bearer $GITHUB_TOKEN" 
      -H "Content-Type: application/json" 
      -d "$QUERY")
    TITLE=$(echo "$RESPONSE" | jq -r '.data.repository.pullRequest.title // empty')
    echo "pr_title=$TITLE" >> "$GITHUB_OUTPUT"
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

We constructed the QUERY variable with the GraphQL query string to get the pull request title. Further, we parsed the response using the jq command to get the title of the pull request and stored it in the pr_title variable.

Finally, let’s add the final step to the workflow that prints the pull request title:

- name: Show PR Title
  if: steps.pr.outputs.pr_title != ''
  run: |
    echo "Pull Request Title: ${{ steps.pr.outputs.pr_title }}"

Great! We’ve got our multi-step workflow ready for use.

6. Conclusion

In this tutorial, we learned multiple ways of getting the title of a pull request. We further explored the GitHub context, gh utility, GitHub REST API endpoints, and the GraphQL API endpoint to solve our use case.