283 lines
9.3 KiB
Markdown
283 lines
9.3 KiB
Markdown
# GitHub PR 代码审查工具
|
||
|
||
`GitHub CLI` `代码审查` `GraphQL` `Pull Request`
|
||
|
||
# gh-pr-review
|
||
[](http://agyn.io)
|
||
|
||
`gh-pr-review` 是一个预编译的 GitHub CLI 扩展,专为高效的 Pull Request 审查而设计。它管理待处理的 GraphQL 审查、展示线程元数据,并可在不克隆仓库的情况下解决讨论。
|
||
|
||
- [快速入门](#快速入门)
|
||
- [审查视图](#审查视图)
|
||
- [后端策略](#后端策略)
|
||
- [其他文档](#其他文档)
|
||
- [1.6.0 版本发布](#160-版本发布)
|
||
|
||
## 快速入门
|
||
|
||
从打开待处理审查到解决线程的最快路径:
|
||
|
||
1. **安装或升级扩展。**
|
||
|
||
```sh
|
||
gh extension install Agyn-sandbox/gh-pr-review
|
||
# 更新已有安装
|
||
gh extension upgrade Agyn-sandbox/gh-pr-review
|
||
```
|
||
|
||
2. **创建待处理审查(GraphQL)。** 记录返回的 `id`(GraphQL 节点)。
|
||
|
||
```sh
|
||
gh pr-review review --start -R owner/repo 42
|
||
|
||
{
|
||
"id": "PRR_kwDOAAABbcdEFG12",
|
||
"state": "PENDING"
|
||
}
|
||
```
|
||
|
||
待处理审查不包含 `submitted_at` 字段;该字段在提交后才会出现。
|
||
|
||
3. **使用待处理审查 ID 添加内联评论(GraphQL)。** 如果提供的是数字 ID 而非所需的 `PRR_…` GraphQL 标识符,`review --add-comment` 命令会快速失败。
|
||
|
||
```sh
|
||
gh pr-review review --add-comment \
|
||
--review-id PRR_kwDOAAABbcdEFG12 \
|
||
--path internal/service.go \
|
||
--line 42 \
|
||
--body "nit: 使用辅助函数" \
|
||
-R owner/repo 42
|
||
|
||
{
|
||
"id": "PRRT_kwDOAAABbcdEFG12",
|
||
"path": "internal/service.go",
|
||
"is_outdated": false,
|
||
"line": 42
|
||
}
|
||
```
|
||
|
||
4. **查看审查线程(GraphQL)。** `review view` 显示待处理审查摘要、线程状态和内联评论元数据。始终包含线程 ID;当需要单独的评论节点标识符时,启用 `--include-comment-node-id`。
|
||
|
||
```sh
|
||
gh pr-review review view --reviewer octocat -R owner/repo 42
|
||
|
||
{
|
||
"reviews": [
|
||
{
|
||
"id": "PRR_kwDOAAABbcdEFG12",
|
||
"state": "COMMENTED",
|
||
"comments": [
|
||
{
|
||
"thread_id": "PRRT_kwDOAAABbcdEFG12",
|
||
"path": "internal/service.go",
|
||
"body": "nit: 建议使用辅助函数",
|
||
"is_resolved": false,
|
||
"is_outdated": false,
|
||
"thread": []
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
使用 `thread_id` 值配合 `comments reply` 继续讨论。如果在自己的待处理审查中回复,请通过 `--review-id` 传入关联的 `PRR_…` 标识符。
|
||
|
||
```sh
|
||
gh pr-review comments reply \
|
||
--thread-id PRRT_kwDOAAABbcdEFG12 \
|
||
--body "已在提交 abc123 中处理后续问题" \
|
||
-R owner/repo 42
|
||
```
|
||
|
||
5. **提交审查(GraphQL)。** 最终确认时复用待处理审查的 `PRR_…` 标识符。成功提交后返回仅含状态的响应。GraphQL 级别的错误以结构化 JSON 形式返回,便于排查。
|
||
|
||
```sh
|
||
gh pr-review review --submit \
|
||
--review-id PRR_kwDOAAABbcdEFG12 \
|
||
--event REQUEST_CHANGES \
|
||
--body "请添加测试" \
|
||
-R owner/repo 42
|
||
|
||
{
|
||
"status": "Review submitted successfully"
|
||
}
|
||
```
|
||
|
||
GraphQL 错误时,命令输出以下内容后以非零状态退出:
|
||
|
||
```json
|
||
{
|
||
"status": "Review submission failed",
|
||
"errors": [
|
||
{ "message": "mutation failed", "path": ["mutation", "submitPullRequestReview"] }
|
||
]
|
||
}
|
||
```
|
||
|
||
6. **查看并解决线程(GraphQL)。** 当没有匹配线程时,数组响应始终为 `[]`。
|
||
|
||
```sh
|
||
gh pr-review threads list --unresolved --mine -R owner/repo 42
|
||
|
||
[
|
||
{
|
||
"threadId": "R_ywDoABC123",
|
||
"isResolved": false,
|
||
"path": "internal/service.go",
|
||
"line": 42,
|
||
"isOutdated": false
|
||
}
|
||
]
|
||
```
|
||
|
||
```sh
|
||
gh pr-review threads resolve --thread-id R_ywDoABC123 -R owner/repo 42
|
||
|
||
{
|
||
"thread_node_id": "R_ywDoABC123",
|
||
"is_resolved": true
|
||
}
|
||
```
|
||
|
||
## 审查视图
|
||
|
||
`gh pr-review review view` 输出 Pull Request 讨论的 GraphQL 快照。响应按"审查 → 父内联评论 → 线程回复"分组,省略可选字段而非返回 `null`。
|
||
|
||
使用组合选择器或显式标志运行:
|
||
|
||
```sh
|
||
gh pr-review review view -R owner/repo --pr 3
|
||
```
|
||
|
||
安装或升级至 **v1.6.0 或更新版本**(仅 GraphQL 线程解析和最简评论回复):
|
||
|
||
```sh
|
||
gh extension install Agyn-sandbox/gh-pr-review
|
||
# 更新已有安装
|
||
gh extension upgrade Agyn-sandbox/gh-pr-review
|
||
```
|
||
|
||
### 命令行为
|
||
|
||
- 每次调用仅执行单个 GraphQL 操作(不混用 REST)。
|
||
- 默认包含所有审查者、审查状态和线程。
|
||
- 回复按 `created_at` 升序排列。
|
||
- 输出仅暴露 `author_login`,不含用户对象或 `html_url` 字段。
|
||
- 可选字段(`body`、`submitted_at`、`line`、`thread`)为空时省略;空回复列表渲染为 `"thread": []`。
|
||
|
||
### 过滤器
|
||
|
||
| 标志 | 用途 |
|
||
| --- | --- |
|
||
| `--reviewer <login>` | 仅包含由 `<login>` 撰写的审查(大小写不敏感)。 |
|
||
| `--states <list>` | 逗号分隔的审查状态(`APPROVED`、`CHANGES_REQUESTED`、`COMMENTED`、`DISMISSED`)。 |
|
||
| `--unresolved` | 仅保留未解决的线程。 |
|
||
| `--not_outdated` | 排除标记为过期的线程。 |
|
||
| `--tail <n>` | 每个线程仅保留最后 `n` 条回复(0 = 全部)。父内联评论始终保留,仅裁剪回复。 |
|
||
| `--include-comment-node-id` | 为父评论和回复添加 GraphQL 评论节点标识符。 |
|
||
|
||
### 示例
|
||
|
||
```sh
|
||
# 默认:返回所有审查、状态、线程
|
||
gh pr-review review view -R owner/repo --pr 3
|
||
|
||
# 仅显示未解决的线程
|
||
gh pr-review review view -R owner/repo --pr 3 --unresolved
|
||
|
||
# 聚焦单个审查者的变更请求;每个线程仅保留最新回复
|
||
gh pr-review review view -R owner/repo --pr 3 --reviewer alice --states CHANGES_REQUESTED --tail 1
|
||
|
||
# 排除过期线程并包含评论节点 ID
|
||
gh pr-review review view -R owner/repo --pr 3 --not_outdated --include-comment-node-id
|
||
```
|
||
|
||
### 输出结构
|
||
|
||
```json
|
||
{
|
||
"reviews": [
|
||
{
|
||
"id": "PRR_…",
|
||
"state": "APPROVED|CHANGES_REQUESTED|COMMENTED|DISMISSED",
|
||
"author_login": "…",
|
||
"body": "…", // 为空时省略
|
||
"submitted_at": "…", // 不存在时省略
|
||
"comments": [ // 无评论时省略
|
||
{
|
||
"thread_id": "PRRT_…",
|
||
"comment_node_id": "PRRC_…", // 未请求时省略
|
||
"path": "…",
|
||
"line": 21, // 为 null 时省略
|
||
"author_login": "…",
|
||
"body": "…",
|
||
"created_at": "…",
|
||
"is_resolved": true,
|
||
"is_outdated": false,
|
||
"thread": [ // 仅回复;升序排列;tail 生效
|
||
{
|
||
"comment_node_id": "PRRC_…", // 未请求时省略
|
||
"author_login": "…",
|
||
"body": "…",
|
||
"created_at": "…"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### 回复线程
|
||
|
||
在回复时使用报告中显示的 `thread_id` 值。在继续自己拥有的待处理审查时,同时提供 `--review-id` 和 `--thread-id`。
|
||
|
||
```sh
|
||
gh pr-review comments reply -R owner/repo --pr 3 \
|
||
--thread-id PRRT_kwDOAAABbcdEFG12 \
|
||
--body "已在提交 abc123 中处理后续问题"
|
||
|
||
gh pr-review comments reply -R owner/repo --pr 3 \
|
||
--thread-id PRRT_kwDOAAABbcdEFG12 \
|
||
--review-id PRR_kwDOAAABbcdEFG12 \
|
||
--body "来自待处理审查的回复"
|
||
```
|
||
|
||
## 后端策略
|
||
|
||
每个命令绑定到单一的 GitHub 后端,没有运行时回退。
|
||
|
||
| 命令 | 后端 | 说明 |
|
||
| --- | --- | --- |
|
||
| `review --start` | GraphQL | 通过 `addPullRequestReview` 开启待处理审查。 |
|
||
| `review --add-comment` | GraphQL | 需要 `PRR_…` 审查节点 ID。 |
|
||
| `review view` | GraphQL | 聚合审查、内联评论和回复(用于获取线程 ID)。 |
|
||
| `review --submit` | GraphQL | 通过 `submitPullRequestReview` 使用 `PRR_…` 审查节点 ID 完成待处理审查(通过内部 `gh api graphql` 包装器执行)。 |
|
||
| `comments reply` | GraphQL | 通过 `addPullRequestReviewThreadReply` 回复;在待处理审查中回复时提供 `--review-id`。 |
|
||
| `threads list` | GraphQL | 枚举 Pull Request 的审查线程。 |
|
||
| `threads resolve` / `unresolve` | GraphQL | 通过 `resolveReviewThread` / `unresolveReviewThread` 变更线程解析状态;提供 GraphQL 线程节点 ID(`PRRT_…`)。 |
|
||
|
||
## 其他文档
|
||
|
||
- [docs/USAGE.md](docs/USAGE.md) — v1.6.0 各命令的输入、输出和示例。
|
||
- [docs/SCHEMAS.md](docs/SCHEMAS.md) — 每种结构化响应的 JSON 结构(可选字段省略而非设为 null)。
|
||
- [docs/AGENTS.md](docs/AGENTS.md) — 面向 Agent 的工作流、提示词和最佳实践。
|
||
|
||
## 设计说明
|
||
|
||
- 每个命令绑定到恰好一个 GitHub 后端:审查视图仅使用 GraphQL,评论列表/回复同样仅使用 GraphQL。可选的 REST 查询仅在转换旧版 ID 时出现。
|
||
- 可选字段完全省略,从不用空字符串或 `null` 占位填充。
|
||
- 输出针对无头环境和 LLM 工作流优化(稳定排序、最少修饰、机器友好的 JSON)。
|
||
|
||
## 开发
|
||
|
||
在本地运行测试套件和代码检查工具,禁用 cgo(与发布构建保持一致):
|
||
|
||
```sh
|
||
CGO_ENABLED=0 go test ./...
|
||
CGO_ENABLED=0 golangci-lint run
|
||
```
|
||
|
||
发布版本使用 [`cli/gh-extension-precompile`](https://github.com/cli/gh-extension-precompile) 工作流构建,为 macOS、Linux 和 Windows 发布二进制文件。 |