git%3Aattach-review-to-pr by neolabhq/context-engineering-kit
npx skills add https://github.com/neolabhq/context-engineering-kit --skill git:attach-review-to-pr本指南解释了如何使用 GitHub CLI (gh) API 或 mcp__github_inline_comment__create_inline_comment(如果前者不可用)为 Pull Request 添加针对特定代码行的审阅评论,类似于 GitHub 网页界面允许对特定代码行进行评论的功能。
如果可用,请使用 mcp__github_inline_comment__create_inline_comment MCP 工具在 Pull Request 上发布针对特定代码行的内联评论。此方法能更好地与 GitHub 网页界面集成,是推荐的方法。
备用方案:如果 MCP 工具不可用,请使用下面描述的 GitHub CLI (gh) API 方法:
/comments 端点(参见添加单条针对特定行的评论)/reviews 端点(参见批量添加多条针对特定行的评论)虽然 gh pr review 提供了基本的审阅功能(批准、请求更改、一般评论),但它。要添加针对特定代码行的评论,您必须使用较低级别的 命令直接调用 GitHub 的 REST API。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
gh api已安装并认证 GitHub CLI:
gh auth status
拥有对您想要审阅的仓库和 Pull Request 的访问权限
GitHub 有两种类型的 PR 评论:
审阅评论可以通过两种方式添加:
/pulls/{pr}/comments 端点/pulls/{pr}/reviews 端点gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
-f body='您的评论内容' \
-f commit_id='<commit-sha>' \
-f path='path/to/file.js' \
-F line=42 \
-f side='RIGHT'
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
body | 字符串 | 是 | 审阅评论的文本(支持 Markdown) |
commit_id | 字符串 | 是 | 要评论的提交的 SHA |
path | 字符串 | 是 | 被评论文件的相对路径 |
line | 整数 | 是 | 差异中的行号(对整数使用 -F) |
side | 字符串 | 是 | RIGHT 表示新增/修改的行,LEFT 表示删除的行 |
start_line | 整数 | 否 | 对于多行评论,起始行号 |
start_side | 字符串 | 否 | 对于多行评论,起始侧 |
-f (--field) - 用于字符串值-F (--field) - 用于整数值(注意大写 F)# 首先,获取 PR 的最新提交 SHA
gh api repos/NeoLabHQ/learning-platform-app/pulls/4 --jq '.head.sha'
# 然后添加您的评论
gh api repos/NeoLabHQ/learning-platform-app/pulls/4/comments \
-f body='考虑在此处添加错误处理。我们是否应该在导航离开前确认课程已成功标记为完成?' \
-f commit_id='e152d0dd6cf498467eadbeb638bf05abe11c64d4' \
-f path='src/components/LessonNavigationButtons.tsx' \
-F line=26 \
-f side='RIGHT'
line 参数指的是差异中的位置,而不是文件中的绝对行号:
start_line 和 line 来指定范围成功时,返回包含评论详情的 JSON 对象:
{
"id": 2532291222,
"pull_request_review_id": 3470545909,
"path": "src/components/LessonNavigationButtons.tsx",
"line": 26,
"body": "考虑在此处添加错误处理...",
"html_url": "https://github.com/NeoLabHQ/learning-platform-app/pull/4#discussion_r2532291222",
"created_at": "2025-11-16T22:40:46Z"
}
要在一个审阅中跨不同文件添加多条评论,请使用带有 JSON 输入的 /reviews 端点。
cat <<'EOF' | gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews --input -
{
"event": "COMMENT",
"body": "总体审阅摘要(可选)",
"comments": [
{
"path": "file1.tsx",
"body": "对文件 1 的评论",
"side": "RIGHT",
"line": 15
},
{
"path": "file2.tsx",
"body": "对文件 2 的评论",
"side": "RIGHT",
"line": 30
}
]
}
EOF
| 事件 | 描述 | 何时使用 |
|---|---|---|
COMMENT | 一般审阅评论 | 仅留下反馈,不涉及批准 |
APPROVE | 批准 PR | 变更看起来不错,可以合并 |
REQUEST_CHANGES | 请求更改 | 必须在合并前解决的问题 |
cat <<'EOF' | gh api repos/NeoLabHQ/learning-platform-app/pulls/4/reviews --input -
{
"event": "COMMENT",
"body": "通过 gh api 测试多条针对特定行的评论",
"comments": [
{
"path": "src/components/CourseCard.tsx",
"body": "由 Claude 生成的测试评论",
"side": "RIGHT",
"line": 15
},
{
"path": "src/components/CourseProgressWidget.tsx",
"body": "由 Claude 生成的测试评论",
"side": "RIGHT",
"line": 30
},
{
"path": "src/components/LessonProgressTracker.tsx",
"body": "由 Claude 生成的测试评论",
"side": "RIGHT",
"line": 20
}
]
}
EOF
{
"id": 3470546747,
"state": "COMMENTED",
"html_url": "https://github.com/NeoLabHQ/learning-platform-app/pull/4#pullrequestreview-3470546747",
"submitted_at": "2025-11-16T22:42:43Z",
"commit_id": "e152d0dd6cf498467eadbeb638bf05abe11c64d4"
}
错误信息:
gh: Validation Failed (HTTP 422)
{"message":"Validation Failed","errors":[{"resource":"PullRequestReview","code":"custom","field":"user_id","message":"user_id can only have one pending review per pull request"}]}
原因: GitHub 只允许每个用户在每个 PR 上有一个待处理(未提交)的审阅。如果您之前通过网页界面或 API 开始了一个审阅但没有提交,它会阻止创建新的审阅。
解决方案 1:提交待处理的审阅
# 检查待处理的审阅
gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews | jq '.[] | select(.state=="PENDING")'
# 通过网页界面提交它,或请用户提交它
解决方案 2:改用单条评论端点
# 添加单独的评论而不创建审阅
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
-f body='评论文本' \
-f commit_id='<sha>' \
-f path='file.tsx' \
-F line=26 \
-f side='RIGHT'
失败的尝试:
# 这不起作用 - GitHub API 接收到的是一个对象,而不是数组
gh api repos/{owner}/{repo}/pulls/{pr}/reviews \
--raw-field 'comments[0][path]=file1.tsx' \
--raw-field 'comments[0][line]=15' \
--raw-field 'comments[1][path]=file2.tsx' \
--raw-field 'comments[1][line]=30'
错误:
Invalid request. For 'properties/comments', {"0" => {...}, "1" => {...}} is not an array.
解决方案: 通过 heredoc 使用 JSON 输入:
cat <<'EOF' | gh api repos/{owner}/{repo}/pulls/{pr}/reviews --input -
{
"comments": [...]
}
EOF
错误信息:
Pull request review thread line must be part of the diff
原因: 该行号在此文件的差异中不存在。
解决方案:
commit_id(PR 中的最新提交)错误信息:
commit_sha is not part of the pull request
解决方案: 获取最新的提交 SHA:
gh api repos/{owner}/{repo}/pulls/{pr_number} --jq '.head.sha'
在添加评论之前,收集必要的信息:
# 获取 PR 详情
gh pr view {pr_number} --json headRefOid,files
# 或使用 API
gh api repos/{owner}/{repo}/pulls/{pr_number} --jq '{commit: .head.sha, files: [.changed_files]}'
# 列出已更改的文件
gh api repos/{owner}/{repo}/pulls/{pr_number}/files --jq '.[] | {filename: .filename, additions: .additions, deletions: .deletions}'
# 检查您是否有待处理的审阅
gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews \
--jq '.[] | select(.state=="PENDING" and .user.login=="YOUR_USERNAME")'
具体且有建设性
引用文档或最佳实践
在请求更改时建议替代方案
对代码建议使用代码块:
考虑使用 async/await:
```typescript async function getData() { const result = await fetch(url); return result.json(); } ```
使用审阅端点来分组相关的评论:
# 用于开发期间的反馈
"event": "COMMENT"
# 当批准时
"event": "APPROVE"
# 当阻止合并时
"event": "REQUEST_CHANGES"
#!/bin/bash
OWNER="NeoLabHQ"
REPO="learning-platform-app"
PR=4
# 获取最新提交
COMMIT=$(gh api repos/$OWNER/$REPO/pulls/$PR --jq '.head.sha')
# 添加评论
gh api repos/$OWNER/$REPO/pulls/$PR/comments \
-f body='考虑将其提取到单独的函数中以提高可测试性' \
-f commit_id="$COMMIT" \
-f path='src/utils/validation.ts' \
-F line=45 \
-f side='RIGHT'
#!/bin/bash
OWNER="NeoLabHQ"
REPO="learning-platform-app"
PR=4
# 创建包含多条评论的审阅
cat <<EOF | gh api repos/$OWNER/$REPO/pulls/$PR/reviews --input -
{
"event": "COMMENT",
"body": "感谢您的 PR!我已经审阅了变更,并有一些建议。",
"comments": [
{
"path": "src/components/CourseCard.tsx",
"body": "考虑记忆化此组件以防止不必要的重新渲染",
"side": "RIGHT",
"line": 25
},
{
"path": "src/utils/courseProgress.ts",
"body": "此函数可能受益于对无效课程 ID 的错误处理",
"side": "RIGHT",
"line": 12
},
{
"path": "src/state/CourseProgressState.ts",
"body": "考虑添加 JSDoc 注释以记录预期行为",
"side": "RIGHT",
"line": 8
}
]
}
EOF
# 评论一系列行(例如,第 10-15 行)
gh api repos/$OWNER/$REPO/pulls/$PR/comments \
-f body='整个代码块可以使用数组解构来简化' \
-f commit_id="$COMMIT" \
-f path='src/utils/parser.ts' \
-F start_line=10 \
-f start_side='RIGHT' \
-F line=15 \
-f side='RIGHT'
#!/bin/bash
# pr-files.sh - 列出 PR 中所有已更改的文件及其行数统计
OWNER="$1"
REPO="$2"
PR="$3"
gh api repos/$OWNER/$REPO/pulls/$PR/files --jq '.[] | "\(.filename): +\(.additions)/-\(.deletions)"'
#!/bin/bash
# check-reviews.sh - 检查 PR 的审阅状态
OWNER="$1"
REPO="$2"
PR="$3"
echo "=== 审阅 ==="
gh api repos/$OWNER/$REPO/pulls/$PR/reviews --jq '.[] | "\(.user.login): \(.state) at \(.submitted_at)"'
echo -e "\n=== 待处理审阅 ==="
gh api repos/$OWNER/$REPO/pulls/$PR/reviews --jq '.[] | select(.state=="PENDING") | "\(.user.login): \(.state)"'
在特定行上创建审阅评论。
端点: https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/comments
参数:
body (字符串,必需):评论文本commit_id (字符串,必需):提交的 SHApath (字符串,必需):文件的相对路径line (整数,必需):差异中的行号side (字符串,必需):"LEFT" 或 "RIGHT"start_line (整数,可选):多行评论的起始行start_side (字符串,可选):多行评论的起始侧创建包含可选针对特定行评论的审阅。
端点: https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/reviews
参数:
event (字符串,必需):"APPROVE"、"REQUEST_CHANGES" 或 "COMMENT"body (字符串,可选):总体审阅评论comments (数组,可选):评论对象数组commit_id (字符串,可选):要审阅的提交的 SHA评论对象:
path (字符串,必需):文件的相对路径body (字符串,必需):评论文本line (整数,必需):差异中的行号side (字符串,必需):"LEFT" 或 "RIGHT"start_line (整数,可选):多行评论的起始行start_side (字符串,可选):多行评论的起始侧每周安装量
214
仓库
GitHub 星标数
699
首次出现
Feb 19, 2026
安装于
opencode208
github-copilot207
codex207
gemini-cli206
kimi-cli204
cursor204
This guide explains how to add line-specific review comments to pull requests using the GitHub CLI (gh) API or mcp__github_inline_comment__create_inline_comment if it not available, similar to how the GitHub UI allows commenting on specific lines of code.
If available , use the mcp__github_inline_comment__create_inline_comment MCP tool for posting line-specific inline comments on pull requests. This approach provides better integration with GitHub's UI and is the recommended method.
Fallback : If the MCP tool is not available, use the GitHub CLI (gh) API methods described below:
/comments endpoint (see Adding a Single Line-Specific Comment)/reviews endpoint (see Adding Multiple Line-Specific Comments Together)While gh pr review provides basic review functionality (approve, request changes, general comments), it does not support line-specific comments directly. To add comments on specific lines of code, you must use the lower-level gh api command to call GitHub's REST API directly.
GitHub CLI installed and authenticated:
gh auth status
Access to the repository and pull request you want to review
GitHub has two types of PR comments:
Review comments can be added in two ways:
/pulls/{pr}/comments endpoint/pulls/{pr}/reviews endpointgh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
-f body='Your comment text here' \
-f commit_id='<commit-sha>' \
-f path='path/to/file.js' \
-F line=42 \
-f side='RIGHT'
| Parameter | Type | Required | Description |
|---|---|---|---|
body | string | Yes | The text of the review comment (supports Markdown) |
commit_id | string | Yes | The SHA of the commit to comment on |
path | string | Yes | Relative path to the file being commented on |
line | integer | Yes | The line number in the diff (use -F for integers) |
-f (--field) - For string values-F (--field) - For integer values (note the capital F)# First, get the latest commit SHA for the PR
gh api repos/NeoLabHQ/learning-platform-app/pulls/4 --jq '.head.sha'
# Then add your comment
gh api repos/NeoLabHQ/learning-platform-app/pulls/4/comments \
-f body='Consider adding error handling here. Should we confirm the lesson was successfully marked as completed before navigating away?' \
-f commit_id='e152d0dd6cf498467eadbeb638bf05abe11c64d4' \
-f path='src/components/LessonNavigationButtons.tsx' \
-F line=26 \
-f side='RIGHT'
The line parameter refers to the position in the diff , not the absolute line number in the file:
start_line and line to specify the rangeOn success, returns a JSON object with comment details:
{
"id": 2532291222,
"pull_request_review_id": 3470545909,
"path": "src/components/LessonNavigationButtons.tsx",
"line": 26,
"body": "Consider adding error handling here...",
"html_url": "https://github.com/NeoLabHQ/learning-platform-app/pull/4#discussion_r2532291222",
"created_at": "2025-11-16T22:40:46Z"
}
To add multiple comments across different files in a single review, use the /reviews endpoint with JSON input.
cat <<'EOF' | gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews --input -
{
"event": "COMMENT",
"body": "Overall review summary (optional)",
"comments": [
{
"path": "file1.tsx",
"body": "Comment on file 1",
"side": "RIGHT",
"line": 15
},
{
"path": "file2.tsx",
"body": "Comment on file 2",
"side": "RIGHT",
"line": 30
}
]
}
EOF
| Event | Description | When to Use |
|---|---|---|
COMMENT | General review comment | Just leaving feedback without approval |
APPROVE | Approve the PR | Changes look good, ready to merge |
REQUEST_CHANGES | Request changes | Issues that must be fixed before merge |
cat <<'EOF' | gh api repos/NeoLabHQ/learning-platform-app/pulls/4/reviews --input -
{
"event": "COMMENT",
"body": "Testing multiple line-specific comments via gh api",
"comments": [
{
"path": "src/components/CourseCard.tsx",
"body": "Test comment generated by Claude",
"side": "RIGHT",
"line": 15
},
{
"path": "src/components/CourseProgressWidget.tsx",
"body": "Test comment generated by Claude",
"side": "RIGHT",
"line": 30
},
{
"path": "src/components/LessonProgressTracker.tsx",
"body": "Test comment generated by Claude",
"side": "RIGHT",
"line": 20
}
]
}
EOF
{
"id": 3470546747,
"state": "COMMENTED",
"html_url": "https://github.com/NeoLabHQ/learning-platform-app/pull/4#pullrequestreview-3470546747",
"submitted_at": "2025-11-16T22:42:43Z",
"commit_id": "e152d0dd6cf498467eadbeb638bf05abe11c64d4"
}
Error Message:
gh: Validation Failed (HTTP 422)
{"message":"Validation Failed","errors":[{"resource":"PullRequestReview","code":"custom","field":"user_id","message":"user_id can only have one pending review per pull request"}]}
Cause: GitHub only allows one pending (unsubmitted) review per user per PR. If you previously started a review through the UI or API and didn't submit it, it blocks new review creation.
Solution 1: Submit the pending review
# Check for pending reviews
gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews | jq '.[] | select(.state=="PENDING")'
# Submit it through the UI or ask the user to submit it
Solution 2: Use the single comment endpoint instead
# Add individual comments without creating a review
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
-f body='Comment text' \
-f commit_id='<sha>' \
-f path='file.tsx' \
-F line=26 \
-f side='RIGHT'
Failed Attempt:
# This does NOT work - GitHub API receives an object, not an array
gh api repos/{owner}/{repo}/pulls/{pr}/reviews \
--raw-field 'comments[0][path]=file1.tsx' \
--raw-field 'comments[0][line]=15' \
--raw-field 'comments[1][path]=file2.tsx' \
--raw-field 'comments[1][line]=30'
Error:
Invalid request. For 'properties/comments', {"0" => {...}, "1" => {...}} is not an array.
Solution: Use JSON input via heredoc:
cat <<'EOF' | gh api repos/{owner}/{repo}/pulls/{pr}/reviews --input -
{
"comments": [...]
}
EOF
Error Message:
Pull request review thread line must be part of the diff
Cause: The line number doesn't exist in the diff for this file.
Solutions:
commit_id (the latest commit in the PR)Error Message:
commit_sha is not part of the pull request
Solution: Get the latest commit SHA:
gh api repos/{owner}/{repo}/pulls/{pr_number} --jq '.head.sha'
Before adding comments, gather necessary information:
# Get PR details
gh pr view {pr_number} --json headRefOid,files
# Or use the API
gh api repos/{owner}/{repo}/pulls/{pr_number} --jq '{commit: .head.sha, files: [.changed_files]}'
# List files changed
gh api repos/{owner}/{repo}/pulls/{pr_number}/files --jq '.[] | {filename: .filename, additions: .additions, deletions: .deletions}'
# Check if you have a pending review
gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews \
--jq '.[] | select(.state=="PENDING" and .user.login=="YOUR_USERNAME")'
Be specific and constructive
Reference documentation or best practices
Suggest alternatives when requesting changes
Use code blocks for code suggestions:
Consider using async/await:
```typescript async function getData() { const result = await fetch(url); return result.json(); } ```
Use the review endpoint to group related comments:
# For feedback during development
"event": "COMMENT"
# When approving
"event": "APPROVE"
# When blocking merge
"event": "REQUEST_CHANGES"
#!/bin/bash
OWNER="NeoLabHQ"
REPO="learning-platform-app"
PR=4
# Get latest commit
COMMIT=$(gh api repos/$OWNER/$REPO/pulls/$PR --jq '.head.sha')
# Add comment
gh api repos/$OWNER/$REPO/pulls/$PR/comments \
-f body='Consider extracting this into a separate function for better testability' \
-f commit_id="$COMMIT" \
-f path='src/utils/validation.ts' \
-F line=45 \
-f side='RIGHT'
#!/bin/bash
OWNER="NeoLabHQ"
REPO="learning-platform-app"
PR=4
# Create review with multiple comments
cat <<EOF | gh api repos/$OWNER/$REPO/pulls/$PR/reviews --input -
{
"event": "COMMENT",
"body": "Thanks for the PR! I've reviewed the changes and have a few suggestions.",
"comments": [
{
"path": "src/components/CourseCard.tsx",
"body": "Consider memoizing this component to prevent unnecessary re-renders",
"side": "RIGHT",
"line": 25
},
{
"path": "src/utils/courseProgress.ts",
"body": "This function could benefit from error handling for invalid course IDs",
"side": "RIGHT",
"line": 12
},
{
"path": "src/state/CourseProgressState.ts",
"body": "Consider adding JSDoc comments to document the expected behavior",
"side": "RIGHT",
"line": 8
}
]
}
EOF
# Comment on a range of lines (e.g., lines 10-15)
gh api repos/$OWNER/$REPO/pulls/$PR/comments \
-f body='This entire block could be simplified using array destructuring' \
-f commit_id="$COMMIT" \
-f path='src/utils/parser.ts' \
-F start_line=10 \
-f start_side='RIGHT' \
-F line=15 \
-f side='RIGHT'
#!/bin/bash
# pr-files.sh - List all files changed in a PR with line counts
OWNER="$1"
REPO="$2"
PR="$3"
gh api repos/$OWNER/$REPO/pulls/$PR/files --jq '.[] | "\(.filename): +\(.additions)/-\(.deletions)"'
#!/bin/bash
# check-reviews.sh - Check review status for a PR
OWNER="$1"
REPO="$2"
PR="$3"
echo "=== Reviews ==="
gh api repos/$OWNER/$REPO/pulls/$PR/reviews --jq '.[] | "\(.user.login): \(.state) at \(.submitted_at)"'
echo -e "\n=== Pending Reviews ==="
gh api repos/$OWNER/$REPO/pulls/$PR/reviews --jq '.[] | select(.state=="PENDING") | "\(.user.login): \(.state)"'
Creates a review comment on a specific line.
Endpoint: https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/comments
Parameters:
body (string, required): Comment textcommit_id (string, required): SHA of commitpath (string, required): Relative file pathline (integer, required): Line number in diffside (string, required): "LEFT" or "RIGHT"start_line (integer, optional): Start line for multi-linestart_side (string, optional): Start side for multi-lineCreates a review with optional line-specific comments.
Endpoint: https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/reviews
Parameters:
event (string, required): "APPROVE", "REQUEST_CHANGES", or "COMMENT"body (string, optional): Overall review commentcomments (array, optional): Array of comment objectscommit_id (string, optional): SHA of commit to reviewComment Object:
path (string, required): Relative file pathbody (string, required): Comment textline (integer, required): Line number in diffside (string, required): "LEFT" or "RIGHT"start_line (integer, optional): Start line for multi-linestart_side (string, optional): Start side for multi-lineWeekly Installs
214
Repository
GitHub Stars
699
First Seen
Feb 19, 2026
Installed on
opencode208
github-copilot207
codex207
gemini-cli206
kimi-cli204
cursor204
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
147,400 周安装
side | string | Yes | RIGHT for new/modified lines, LEFT for deleted lines |
start_line | integer | No | For multi-line comments, the starting line |
start_side | string | No | For multi-line comments, the starting side |