fix(utils): batch push and add preview mode to address-reviews - #415
openshift-merge-bot[bot] merged 5 commits into
Conversation
Move git push from per-comment to a single push after all comments are processed and all replies are posted. This eliminates the prompt conflict with CI jobs that need to control push timing, reduces unnecessary CI triggers from multiple force-pushes, and ensures replies are posted before any push that could trigger a Prow self-abort. New flow: commit locally per comment → post all replies → push once → verify push. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When running interactively, preview each comment's proposed action and draft reply before proceeding. The user can approve, edit, or skip each comment. In CI mode (-p flag), previews are skipped for autonomous operation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WalkthroughThe Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Add back uncommitted changes check and failure reporting to the verify-push step. Since replies are posted before the push, a failed push needs to be surfaced to the user rather than silently ignored. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add back the technical explanation format (3-5 sentences with file:line references) for when a requested change is declined. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
a8c757b to
6ae6242
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@plugins/utils/commands/address-reviews.md`:
- Around line 193-195: Add a language tag to the fenced code block containing
the GitHub CLI API command to satisfy markdownlint MD040; locate the fenced
block that wraps the command "gh api
repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f
body=\"<reply>\"" and change the opening fence from ``` to ```bash so the block
is explicitly marked as bash.
- Around line 194-197: Update Step 4a to route replies by feedback type instead
of attempting a single inline endpoint with fallback: for inline diff comments
use the review_comment endpoint (gh api
repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f
body="<reply>"), for PR conversation comments use the issue_comment flow (gh pr
comment <PR_NUMBER> --body="@<author> <reply>"), and for review threads (if
tracked) call the GraphQL addPullRequestReviewThreadReply mutation; ensure the
document and any implementation references to "Step 4a" explicitly map each
feedback type to its specific endpoint and state that failures must be reported
and ignored (do not fallback to another channel).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 2e2db6a5-834d-4f92-a2f6-12a40b1c1ce2
📒 Files selected for processing (5)
.claude-plugin/marketplace.jsonPLUGINS.mddocs/data.jsonplugins/utils/.claude-plugin/plugin.jsonplugins/utils/commands/address-reviews.md
| ``` | ||
| gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f body="<reply>" | ||
| ``` |
There was a problem hiding this comment.
Add a language tag to the fenced code block.
This triggers markdownlint MD040 (fenced-code-language).
📝 Proposed fix
- ```
+ ```bash
gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f body="<reply>"</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)
[warning] 193-193: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/utils/commands/address-reviews.md` around lines 193 - 195, Add a
language tag to the fenced code block containing the GitHub CLI API command to
satisfy markdownlint MD040; locate the fenced block that wraps the command "gh
api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f
body=\"<reply>\"" and change the opening fence from ``` to ```bash so the block
is explicitly marked as bash.
| gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f body="<reply>" | ||
| ``` | ||
| If fails: `gh pr comment <PR_NUMBER> --body="@<author> <reply>"` | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, locate and read the file
find . -name "address-reviews.md" -type f 2>/dev/null | head -5Repository: openshift-eng/ai-helpers
Length of output: 111
🏁 Script executed:
# Read the file around lines 194-197 to see context
wc -l ./plugins/utils/commands/address-reviews.mdRepository: openshift-eng/ai-helpers
Length of output: 115
🏁 Script executed:
# Read lines around 194-197 with context
sed -n '185,210p' ./plugins/utils/commands/address-reviews.md | cat -nRepository: openshift-eng/ai-helpers
Length of output: 999
🌐 Web query:
GitHub API pull request comments replies endpoint REST
💡 Result:
For pull request review comments (inline diff comments), GitHub’s REST API supports creating replies via:
- Create a reply to a review comment:
POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies(wherecomment_idmust be a top-level review comment; replies-to-replies aren’t supported). [1]
There is no separate “list replies” REST endpoint; to fetch replies you typically:
- List all review comments on the PR and then filter items where
in_reply_to_idequals the top-level comment’sid. [1]
Source
- [1] GitHub Docs — “REST API endpoints for pull request review comments” (includes “Create a reply for a review comment” and the
in_reply_to_idfield) https://docs.github.com/en/rest/pulls/comments
🌐 Web query:
GitHub API pull request review types issue_comment review_comment feedback channels
💡 Result:
PR “feedback channels” in GitHub APIs (and how they map)
- PR conversation comments (a.k.a. “issue comments” on the PR)
- Where they appear in UI: PR Conversation tab (not tied to a diff line).
- REST API: Issue comments endpoints (
/repos/{owner}/{repo}/issues/{issue_number}/comments)—because every pull request is also an issue. [1] - GitHub Actions trigger:
issue_comment(for comments created/edited/deleted on the PR conversation). [2]
- Inline diff comments (a.k.a. “pull request review comments”)
- Where they appear in UI: on specific files/lines in the Files changed diff (threaded as part of review discussions).
- REST API: Pull request review comments endpoints (
/repos/{owner}/{repo}/pulls/comments/...). [3] - GitHub Actions trigger:
pull_request_review_comment. [2]
- A submitted review (the “review type”: approve / request changes / comment)
- Where they appear in UI: the review “summary” (optionally with inline comments included).
- REST API: Pull request reviews endpoint (
POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews) withevent:APPROVE,REQUEST_CHANGES,COMMENT- If
eventis omitted, the review is created asPENDING(a pending review you submit later). [4]
- GitHub Actions trigger:
pull_request_reviewwith activity typessubmitted,edited,dismissed(and you can checkgithub.event.review.state). [2]
- GraphQL naming (helpful when you see different words)
- Mutating a review uses
PullRequestReviewEvent:APPROVE,REQUEST_CHANGES,COMMENT,DISMISS. [5] - Stored review state is
PullRequestReviewState:APPROVED,CHANGES_REQUESTED,COMMENTED,DISMISSED,PENDING. [5]
Sources
[1] (docs.github.com)
[2] (docs.github.com)
[3] (docs.github.com)
[4] (docs.github.com)
[5] (docs.github.com)
Citations:
- 1: https://docs.github.com/rest/issues/issues?utm_source=openai
- 2: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows?utm_source=openai
- 3: https://docs.github.com/en/rest/pulls/comments?utm_source=openai
- 4: https://docs.github.com/enterprise-server%403.19/rest/pulls/reviews?utm_source=openai
- 5: https://docs.github.com/v4/enum/repocreateauditentryvisibility?utm_source=openai
🏁 Script executed:
# Search for the "one response mechanism" rule or similar constraints in the file
rg -i "one response|mechanism|feedback type|channel" ./plugins/utils/commands/address-reviews.md -A 2 -B 2Repository: openshift-eng/ai-helpers
Length of output: 616
🏁 Script executed:
# Read Step 3 to understand what types of feedback are extracted
sed -n '1,193p' ./plugins/utils/commands/address-reviews.md | tail -60 | cat -nRepository: openshift-eng/ai-helpers
Length of output: 2806
🏁 Script executed:
# Find Step 3 content
sed -n '1,150p' ./plugins/utils/commands/address-reviews.md | grep -n "Step 3" -A 40 | head -50Repository: openshift-eng/ai-helpers
Length of output: 1793
🏁 Script executed:
# Read the full Step 3 section
sed -n '110,180p' ./plugins/utils/commands/address-reviews.md | cat -nRepository: openshift-eng/ai-helpers
Length of output: 3376
🌐 Web query:
GitHub API comment type detection review comment issue comment determine type
💡 Result:
REST API (v3): distinguish by the resource type / fields
1) Pull request review comment (inline diff comment) = PullRequestReviewComment
- Comes from PR review comment endpoints like
GET /repos/{owner}/{repo}/pulls/comments/.../pulls/comments/{comment_id}. - Has review/diff-specific fields such as
pull_request_review_id,diff_hunk,path,position,commit_id, and sometimesin_reply_to_id. [1]
2) Issue comment (works for both Issues and PR “conversation” comments) = IssueComment
- Comes from issue comment endpoints like
GET /repos/{owner}/{repo}/issues/commentsorGET /repos/{owner}/{repo}/issues/{issue_number}/comments. - Has fields like
issue_urland URLs shaped like/issues/comments/{id}. [2]
3) If it’s an IssueComment, how to tell “issue vs PR conversation”?
- Fetch the parent issue via the comment’s
issue_url, then check whether the returned issue JSON contains thepull_requestkey:- present ⇒ it’s a pull request (conversation comment)
- absent ⇒ it’s a plain issue
GitHub explicitly notes you can identify PRs from Issues endpoints by thepull_requestkey. [3]
GraphQL API (v4): use __typename
Query the node and branch by type:
query($id: ID!) {
node(id: $id) {
__typename
... on IssueComment { id url }
... on PullRequestReviewComment { id url path diffHunk }
}
}__typename will be IssueComment vs PullRequestReviewComment.
Sources
- GitHub REST: Pull request review comments (example response includes
pull_request_review_id,diff_hunk,path, etc.). [1] - GitHub REST: Issue comments (example response includes
issue_url; used for issues and PR conversation comments). [2] - GitHub REST: Issues endpoints note PRs can be identified by the
pull_requestkey. [3]
[1] (docs.github.com)
[2] (docs.github.com)
[3] (docs.github.com)
Citations:
- 1: https://docs.github.com/en/rest/pulls/comments?utm_source=openai
- 2: https://docs.github.com/en/rest/issues/comments
- 3: https://docs.github.com/en/rest/issues/issues
🌐 Web query:
GitHub GraphQL mutation review thread reply create
💡 Result:
To create a reply in an existing PR review thread with the GitHub GraphQL v4 API, use the mutation addPullRequestReviewThreadReply, which takes:
pullRequestReviewThreadId(required, the thread’s node ID)body(required, reply text)pullRequestReviewId(optional, if you want the reply to belong to a pending review) [1], [2]
1) Get the review thread node ID
Query the PR’s review threads and pick the right id:
query($owner:String!, $name:String!, $number:Int!) {
repository(owner:$owner, name:$name) {
pullRequest(number:$number) {
reviewThreads(first: 50) {
nodes {
id
isResolved
comments(first: 20) {
nodes { id body author { login } }
}
}
}
}
}
}(You’ll use the thread id as pullRequestReviewThreadId.) [1]
2) Reply to that thread
mutation($threadId:ID!, $body:String!) {
addPullRequestReviewThreadReply(input:{
pullRequestReviewThreadId: $threadId,
body: $body
}) {
comment { id url body }
}
}This creates a new reply comment in that thread. [1], [2]
🌐 Web query:
GitHub REST API PullRequestReviewComment IssueComment type name terminology
💡 Result:
In GitHub REST API, the “type names” like PullRequestReviewComment and IssueComment don’t exist as formal REST resource names—they’re GraphQL object type names. In REST, GitHub uses endpoint terminology instead:
-
Issue (and PR “Conversation”) comments
REST name/area: Issue comments — “comments on issues and pull requests” (because every pull request is an issue).
Typical REST endpoints:/repos/{owner}/{repo}/issues/{issue_number}/comments,/repos/{owner}/{repo}/issues/comments/{comment_id}. [1] -
Inline code review comments on diffs (“Files changed”)
REST name/area: Pull request review comments.
Typical REST endpoints:/repos/{owner}/{repo}/pulls/{pull_number}/comments,/repos/{owner}/{repo}/pulls/comments/{comment_id}. [2]
In GraphQL, the corresponding object types are explicitly named:
IssueComment= comment on an Issue (and PR conversation, since PRs are Issues). [1][3]PullRequestReviewComment= inline review comment on a PR diff. [2][3]
Rule of thumb: if the comment is on the PR Conversation timeline, it’s an issue comment; if it’s anchored to a file/line in the diff, it’s a pull request review comment. [1][2]
Sources: [1] https://docs.github.com/en/rest/issues/comments, [2] https://docs.github.com/en/rest/pulls/comments, [3] https://docs.github.com/en/graphql/reference/objects
Update Step 4a to route replies by feedback type instead of using a single endpoint with fallback.
The current implementation tries posting all replies via the inline review comment endpoint and falls back to a general PR comment on failure. This violates the documented "One response per feedback" rule which explicitly states: "NEVER respond to the same feedback via both mechanisms."
Replace the single endpoint with type-specific routing:
- Inline diff comments (review_comment):
gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f body="<reply>" - PR conversation comments (issue_comment):
gh pr comment <PR_NUMBER> --body="@<author> <reply>" - Review threads (if tracked): use the GraphQL
addPullRequestReviewThreadReplymutation
For each type, if posting fails, report the failure and continue—do not silently switch to another channel.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@plugins/utils/commands/address-reviews.md` around lines 194 - 197, Update
Step 4a to route replies by feedback type instead of attempting a single inline
endpoint with fallback: for inline diff comments use the review_comment endpoint
(gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f
body="<reply>"), for PR conversation comments use the issue_comment flow (gh pr
comment <PR_NUMBER> --body="@<author> <reply>"), and for review threads (if
tracked) call the GraphQL addPullRequestReviewThreadReply mutation; ensure the
document and any implementation references to "Step 4a" explicitly map each
feedback type to its specific endpoint and state that failures must be reported
and ignored (do not fallback to another channel).
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bryan-cox, muraee The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Summary
--previewflag: Opt-in interactive preview mode that shows each comment's proposed action and draft reply before proceeding. Users can approve, edit, or skip each comment.Motivation
The
address-review-commentspresubmit job in openshift/release pushes commits back to the PR branch, which can cause Prow to abort the running job. Previously, the skill instructed Claude to push after every change ("A commit without a push is incomplete. You MUST push."), which conflicted with the CI script's "Do NOT push" override. Now both the skill and CI agree: commit locally during processing, post all replies, then push once at the very end.Test plan
/utils:address-reviews <PR> --previewlocally and verify each comment shows a preview before acting/utils:address-reviews <PR>locally and verify autonomous mode (no previews)/test address-review-commentson a hypershift PR🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
--previewflag toutils:address-reviewscommand enabling interactive review mode that displays proposed actions and draft replies for approval before execution.Chores