review-pr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReview PR Comments
处理PR评论
Fetch, evaluate, and address PR review comments from GitHub. Many reviewer comments reference outdated code or misunderstand the logic — always verify against the actual codebase before acting.
从GitHub获取、评估并处理PR评审评论。许多评审者的评论引用了过时代码或误解了逻辑——在采取行动前务必对照实际代码库进行验证。
Process
流程
This is a single-pass flow. Fetch comments, read files, evaluate, present assessment, reply to all comments, resolve all threads, and show the final summary — all without pausing for user confirmation.
这是单流程执行:获取评论、读取文件、评估、呈现评估结果、回复所有评论、解决所有线程,并显示最终总结——全程无需等待用户确认。
1. Find the PR
1. 查找PR
If no PR number is provided, find the PR for the current branch:
bash
gh pr list --head $(git branch --show-current) --json number,title --jq '.[0]'如果未提供PR编号,则查找当前分支对应的PR:
bash
gh pr list --head $(git branch --show-current) --json number,title --jq '.[0]'2. Fetch Review Comments
2. 获取评审评论
Fetch comments with their IDs:
bash
gh api repos/{owner}/{repo}/pulls/{number}/comments --jq '.[] | {id: .id, path: .path, line: (.line // .original_line), body: .body, in_reply_to_id: .in_reply_to_id}'Filter to only top-level comments (where is null).
in_reply_to_id获取带ID的评论:
bash
gh api repos/{owner}/{repo}/pulls/{number}/comments --jq '.[] | {id: .id, path: .path, line: (.line // .original_line), body: .body, in_reply_to_id: .in_reply_to_id}'过滤仅保留顶级评论(即为null的评论)。
in_reply_to_id3. Read Referenced Files (Critical Step)
3. 读取引用文件(关键步骤)
Before evaluating any comment, read the actual current code. Reviewers often:
- Reference line numbers from an older commit
- Misread the logic
- Comment on code that's already been fixed
For each unique file path, read the file and verify:
- Does the line number match what the reviewer is describing?
- Has the issue already been addressed?
- Is the reviewer's understanding of the code correct?
在评估任何评论前,务必读取当前实际代码。评审者常出现以下情况:
- 引用旧提交的行号
- 误解逻辑
- 针对已修复的代码发表评论
针对每个唯一文件路径,读取文件并验证:
- 评审者描述的内容是否与对应行号的代码匹配?
- 问题是否已被解决?
- 评审者对代码的理解是否正确?
4. Evaluate All Comments
4. 评估所有评论
Categorize each comment:
| Category | Criteria | Response |
|---|---|---|
| Already addressed | Issue was fixed in a subsequent commit, or reviewer misread the code | Explain what the code actually does |
| Fix | Valid bug, security issue, or typo that exists in current code | Implement the fix |
| Won't fix | Over-engineering, style preference, feature request, or would break consistency | Explain reasoning |
将每个评论分类:
| 分类 | 判定标准 | 处理方式 |
|---|---|---|
| 已处理 | 问题在后续提交中已修复,或评审者误解了代码 | 说明代码实际功能 |
| 需要修复 | 当前代码中存在有效的bug、安全问题或拼写错误 | 实施修复 |
| 暂不修复 | 过度设计、风格偏好、功能需求,或修改会破坏一致性 | 说明理由 |
5. Present Assessment, Reply, and Resolve
5. 呈现评估结果、回复并解决线程
Do all of this in one pass — no pausing for user confirmation. Present your assessment, reply to each comment, and resolve all threads immediately.
Present ALL comments with your assessment:
undefined所有操作一次性完成——无需等待用户确认。呈现评估结果、回复每条评论并立即解决所有线程。
展示所有评论及评估结果:
undefinedPR #[number]: [title]
PR #[number]: [title]
Found [X] review comments. Here's my assessment:
共找到[X]条评审评论。以下是评估结果:
1. path/file.ts:42
— Already addressed
path/file.ts:421. path/file.ts:42
— 已处理
path/file.ts:42[comment body]
Issue: Reviewer concerned about X
Actual code: Lines 26-34 already handle this — [brief explanation]
[评论内容]
问题:评审者关注X点
实际代码:第26-34行已处理该问题——[简要说明]
2. path/other.ts:15
— Won't fix
path/other.ts:152. path/other.ts:15
— 暂不修复
path/other.ts:15[comment body]
Issue: Reviewer wants X
Why skip: [Over-engineering / Matches existing pattern / Feature request / etc]
[评论内容]
问题:评审者希望实现X
不修复原因:[过度设计 / 与现有模式一致 / 功能需求 / 其他]
3. path/file.ts:88
— Fix
path/file.ts:883. path/file.ts:88
— 需要修复
path/file.ts:88[comment body]
Issue: Typo in user-facing string
Proposed change: Change "Jumpope" to "Jump Rope"
[评论内容]
问题:用户可见字符串存在拼写错误
修复方案:将"Jumpope"改为"Jump Rope"
Summary
总结
- Already addressed: 6 comments
- Won't fix: 8 comments
- Fix: 2 comments
Then **immediately** reply to all comments and resolve all threads (steps 6-7 below). Don't wait for user input.- 已处理:6条评论
- 暂不修复:8条评论
- 需要修复:2条评论
随后**立即**回复所有评论并解决所有线程(见下方步骤6-7),无需等待用户输入。6. Reply to Comments
6. 回复评论
For Already addressed comments, reply explaining the current state:
bash
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="This is already handled — lines 26-34 fetch the authenticated user and verify user.id === state before proceeding. If they don't match, it rejects with a CSRF error."For Won't fix comments, reply with concise reasoning:
bash
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="Won't fix — this matches the exact pattern used for the other integrations in the same file. Changing just this one would be inconsistent."For Fix comments, implement the fix first, then reply:
bash
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="Fixed in abc1234"对于已处理的评论,回复说明当前代码状态:
bash
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="该问题已处理——第26-34行会获取已认证用户,并在继续前验证user.id === state。若不匹配,则会返回CSRF错误。"对于暂不修复的评论,回复简洁说明理由:
bash
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="暂不修复——这与同一文件中其他集成的模式完全一致。仅修改这一处会破坏一致性。"对于需要修复的评论,先实施修复,再回复:
bash
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="已在abc1234提交中修复"7. Resolve All Threads
7. 解决所有线程
First, get all unresolved thread IDs:
bash
cat << 'QUERY' | gh api graphql --input - --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | {threadId: .id, commentId: .comments.nodes[0].databaseId}'
{"query": "query($owner: String!, $repo: String!, $pr: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $pr) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 1) { nodes { databaseId } } } } } } }", "variables": {"owner": "OWNER", "repo": "REPO", "pr": 123}}
QUERYThen resolve each thread by ID:
bash
cat << 'QUERY' | gh api graphql --input -
{"query": "mutation { resolveReviewThread(input: {threadId: \"THREAD_ID_HERE\"}) { thread { isResolved } } }"}
QUERY首先获取所有未解决的线程ID:
bash
cat << 'QUERY' | gh api graphql --input - --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | {threadId: .id, commentId: .comments.nodes[0].databaseId}'
{"query": "query($owner: String!, $repo: String!, $pr: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $pr) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 1) { nodes { databaseId } } } } } } }", "variables": {"owner": "OWNER", "repo": "REPO", "pr": 123}}
QUERY然后通过ID解决每个线程:
bash
cat << 'QUERY' | gh api graphql --input -
{"query": "mutation { resolveReviewThread(input: {threadId: \"THREAD_ID_HERE\"}) { thread { isResolved } } }"}
QUERY8. Final Summary
8. 最终总结
After replying and resolving, show the final summary:
undefined完成回复和解决后,展示最终总结:
undefinedReview Complete
评审完成
All 16 conversations resolved.
所有16条讨论已解决。
Already addressed (6)
已处理(6条)
| Comment | Explanation |
|---|---|
| State validation | Already validates user.id === state at lines 26-34 |
| HR zones docs | Comments already say "milliseconds", not "percentage" |
| 评论内容 | 说明 |
|---|---|
| 状态验证 | 已在第26-34行验证user.id === state |
| HR区间文档 | 注释已说明“毫秒”,而非“百分比” |
Won't fix (8)
暂不修复(8条)
| Comment | Reason |
|---|---|
| Form semantics | Matches existing pattern for other integrations |
| Rate limiting | Self-heals on next cron run, over-engineering |
| 评论内容 | 理由 |
|---|---|
| 表单语义 | 与其他集成的现有模式一致 |
| 速率限制 | 下次定时任务运行时会自动恢复,属于过度设计 |
Fixed (2)
已修复(2条)
| Commit | Fix |
|---|---|
| Fixed typo "Jumpope" → "Jump Rope" |
**Important**: The entire flow (assess → reply → resolve → summarize) happens in one pass. Don't pause to ask "should I proceed?" — just do it.
---| 提交记录 | 修复内容 |
|---|---|
| 修复拼写错误“Jumpope”→“Jump Rope” |
**重要提示**:整个流程(评估→回复→解决→总结)一次性完成。不要暂停询问“是否继续?”——直接执行即可。
---Evaluation Guidelines
评估指南
Already Addressed — Explain, don't fix
已处理——说明而非修复
Common patterns where the reviewer is wrong:
- Reviewer references wrong line numbers: Code has changed since they reviewed
- Reviewer misread the logic: e.g., thinks condition is inverted when it's correct
- Issue was already fixed: Subsequent commits addressed it
- Code exists elsewhere: The check/validation happens in a different function
Response template:
"This is already handled — [specific location] does [what it does]. [Brief explanation of why it's correct]."
评审者常见错误场景:
- 评审者引用错误行号:自评审以来代码已变更
- 评审者误解逻辑:例如,认为条件判断颠倒,但实际正确
- 问题已被修复:后续提交已解决该问题
- 代码在其他位置存在:检查/验证逻辑在其他函数中实现
回复模板:
“该问题已处理——[具体位置]实现了[功能]。[简要说明为何正确]。”
Fix — Implement and commit
需要修复——实施并提交
Only fix issues that:
- Actually exist in the current code
- Are bugs, security issues, or typos
- Can be verified by reading the file
仅修复以下问题:
- 当前代码中确实存在的问题
- 属于bug、安全问题或拼写错误
- 可通过读取文件验证的问题
Won't Fix — Explain reasoning
暂不修复——说明理由
| Reason | Response template |
|---|---|
| Matches existing pattern | "Won't fix — this matches the exact pattern of X, Y, and Z in the same file. Changing just this would be inconsistent." |
| Over-engineering | "Won't fix — [the failure mode] will fail obviously / self-heal on retry / is handled by [existing mechanism]." |
| Feature request | "Won't fix — this is a feature request rather than a bug. The current flow works: [what it does]. Out of scope for this PR." |
| Product decision | "Won't fix — this is a product decision, not a bug. [Current behavior] is intentional because [reason]." |
| Would break things | "Won't fix — this would break [existing behavior / consistency with X]." |
| 理由 | 回复模板 |
|---|---|
| 与现有模式一致 | “暂不修复——这与同一文件中X、Y、Z的模式完全一致。仅修改这一处会破坏一致性。” |
| 过度设计 | “暂不修复——[失败场景]会明显报错/重试时自动恢复/已由[现有机制]处理。” |
| 功能需求 | “暂不修复——这属于功能需求而非bug。当前流程可正常运行:[功能描述]。超出本PR的范围。” |
| 产品决策 | “暂不修复——这是产品决策,而非bug。[当前行为]是有意设计的,原因是:[理由]。” |
| 会破坏现有功能 | “暂不修复——这会破坏[现有功能 / 与X的一致性]。” |
Common Reviewer Misunderstandings
评审者常见误解
Inverted conditions
条件判断颠倒
Reviewers often misread boolean logic. Example:
typescript
// "Refresh if expires in less than 5 minutes"
if (expiry.getTime() - Date.now() > 5 * 60 * 1000) {
return integration.access_token!; // Token is fresh, return early
}
// Proceed to refresh...Reviewer says: "Condition is inverted, tokens never refresh"
Reality: Condition is correct — returns early when fresh, refreshes when stale.
评审者常误读布尔逻辑。示例:
typescript
// "如果过期时间少于5分钟则刷新"
if (expiry.getTime() - Date.now() > 5 * 60 * 1000) {
return integration.access_token!; // 令牌有效,提前返回
}
// 执行刷新...评审者评论:“条件判断颠倒,令牌永远不会刷新”
实际情况:条件判断正确——令牌有效时提前返回,过期时执行刷新。
Missing validation that exists
缺失已存在的验证
Reviewer says: "State parameter not validated"
Reality: Lines 26-34 already validate it.
Always check if the validation exists before agreeing.
评审者评论:“未验证State参数”
实际情况:第26-34行已实现验证。
在同意前务必确认验证是否存在。
Tokens in error messages
错误消息中的令牌
Reviewer says: "Sensitive tokens logged in error messages"
Reality: The error logs the API's error response, not our tokens.
Read what's actually in the error string.
评审者评论:“敏感令牌被记录在错误消息中”
实际情况:错误日志记录的是API的错误响应,而非我方令牌。
务必读取错误字符串的实际内容。
Code that doesn't exist at that line
行号对应的代码不存在
Reviewer references line 174, but file only has 161 lines.
The file has changed since the review.
评审者引用第174行,但文件仅有161行。
自评审以来文件已变更。
Key Principles
核心原则
- Single-pass execution: Don't pause to ask "should I proceed?" — assess, reply, resolve, and summarize in one flow
- Verify before acting: Always read the actual file before evaluating a comment
- Trust the codebase: If existing patterns work, new code should match them
- Explain, don't just dismiss: Skipped comments deserve clear explanations
- Resolve everything: All threads should be resolved, whether fixed or explained
- Be concise: Responses should be 1-2 sentences, not paragraphs
- 单流程执行:不要暂停询问“是否继续?”——在一个流程中完成评估、回复、解决和总结
- 验证后再行动:评估评论前务必读取实际文件
- 信任代码库:如果现有模式可行,新代码应与之保持一致
- 说明理由,而非仅拒绝:未处理的评论需要清晰的解释
- 解决所有问题:所有线程都应被解决,无论是否修复
- 简洁明了:回复应控制在1-2句话,避免长篇大论