1. 概述
GitHub Actions 是一个与 GitHub 生态深度集成的强大 CI/CD 平台。在处理 Pull Request(PR)时,我们经常需要获取一些元数据,例如 PR 编号、PR 标题、提交 SHA 等。其中,PR 标题在根据标题模式触发流程时尤其有用。
在本文中,我们将探讨如何在 GitHub Actions 中获取 Pull Request 的标题,包括使用 GitHub 上下文、GitHub CLI、GitHub REST API 以及 GraphQL API 等多种方式。
2. 使用 GitHub 上下文
当工作流由 pull_request
事件触发时,GitHub 会在 github
上下文中自动包含 PR 的相关信息。
以下是一个完整的 workflow 示例:
name: "通过 GitHub 上下文显示 PR 标题"
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: 显示 PR 标题
run: 'echo "PR 标题: ${{ github.event.pull_request.title }}"'
✅ 优点:
- 无需额外工具或 API 调用
- 适用于
pull_request
类型事件
❌ 缺点:
- 无法用于
push
或workflow_dispatch
等其他事件类型
3. 使用 GitHub CLI(gh)
GitHub CLI(gh
)是一个功能强大的命令行工具,可用于与 GitHub 交互。我们可以通过它获取 PR 标题。
3.1. 通过 PR 编号获取
name: "通过 gh CLI 获取 PR 标题"
on:
pull_request:
types:
- opened
...
jobs:
get-title:
runs-on: ubuntu-latest
steps:
- name: 使用 gh pr view 获取 PR 标题
if: github.event_name == 'pull_request'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
title=$(gh pr view ${{ github.event.pull_request.number }} \
--repo ${{ github.repository }} \
--json title -q .title)
echo "PR 标题: $title"
3.2. 通过分支名获取
GitHub 每个分支只能有一个打开的 PR,因此我们也可以通过分支名来查找 PR:
name: "通过 gh CLI 获取 PR 标题"
on:
pull_request:
types:
- opened
...
push:
workflow_dispatch:
jobs:
get-title:
runs-on: ubuntu-latest
steps:
- name: 获取当前分支的 PR 标题
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 "找到 PR #$pr_number,标题为: $pr_title"
else
echo "未找到分支 $branch 的开放 PR"
fi
✅ 优点:
- 支持多种事件类型(
pull_request
,push
,workflow_dispatch
) - 无需手动维护 PR 编号
4. 使用 GitHub REST API
如果你希望流程更通用或跨平台,可以使用 GitHub REST API 来获取 PR 标题。
name: "通过 REST API 获取 PR 标题"
on:
pull_request:
types:
- opened
...
push:
workflow_dispatch:
jobs:
get-title:
runs-on: ubuntu-latest
steps:
- name: 获取当前分支的 PR 标题
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"
✅ 优点:
- 不依赖
gh
CLI,适用于所有支持 curl 的环境 - 可以灵活构造请求
⚠️ 注意:
- 需要处理分页和错误情况(例如无匹配 PR)
5. 使用 GitHub GraphQL API
当你需要获取 PR 的更多信息(如标题、作者、状态、评论等)时,GraphQL API 通常更高效。
以下是一个完整的多步骤 workflow 示例:
第一步:获取 PR 编号
- name: 确定 PR 编号
id: pr-info
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
echo "pr_number=${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
else
echo "尝试通过提交 SHA 查找 PR..."
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 "该提交没有关联的 PR"
echo "pr_number=" >> "$GITHUB_OUTPUT"
exit 0
fi
PR_NUMBER=$(basename "$PR_URL")
echo "找到 PR #$PR_NUMBER"
echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
fi
第二步:调用 GraphQL 查询
- name: 通过 GraphQL 获取 PR 标题
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 }}
第三步:显示 PR 标题
- name: 显示 PR 标题
if: steps.pr.outputs.pr_title != ''
run: |
echo "Pull Request 标题: ${{ steps.pr.outputs.pr_title }}"
✅ 优点:
- 支持一次获取多个字段,减少请求次数
- 更适合复杂查询场景
❌ 缺点:
- 学习曲线略高
- 构造查询语句较复杂
6. 总结
本文介绍了多种在 GitHub Actions 中获取 Pull Request 标题的方法:
方法 | 适用场景 | 是否支持非 PR 事件 | 是否推荐 |
---|---|---|---|
GitHub 上下文 | pull_request 事件 |
❌ | ✅ |
gh CLI(PR 编号) |
有编号时 | ✅ | ✅ |
gh CLI(分支名) |
无编号但有分支 | ✅ | ✅ |
REST API | 所有场景 | ✅ | ✅ |
GraphQL API | 多字段查询 | ✅ | ✅(复杂场景推荐) |
📌 踩坑提醒:
pull_request
以外的事件没有github.event.pull_request
上下文,直接使用会报错。- 使用 REST API 时要注意分页问题,
jq
是解析 JSON 的好帮手。 - GraphQL 查询需要构造 JSON payload,注意格式和引号的转义。
根据你的实际需求选择合适的方法,可以大大简化 CI/CD 流程的开发与维护。