Skip to content

fix(utils): batch push and add preview mode to address-reviews - #415

Merged
openshift-merge-bot[bot] merged 5 commits into
openshift-eng:mainfrom
bryan-cox:fix/address-reviews-batch-push
Apr 10, 2026
Merged

openshift-merge-bot[bot] merged 5 commits into
openshift-eng:mainfrom
bryan-cox:fix/address-reviews-batch-push

Conversation

@bryan-cox

@bryan-cox bryan-cox commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Batch push to end of workflow: Instead of pushing after each comment change, the skill now commits locally during Step 3 and pushes once at the end in Step 4 (after all replies are posted). This eliminates the prompt conflict with CI jobs that need to control push timing and prevents mid-execution self-abort in Prow presubmit jobs.
  • Add --preview flag: 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-comments presubmit 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

  • Run /utils:address-reviews <PR> --preview locally and verify each comment shows a preview before acting
  • Run /utils:address-reviews <PR> locally and verify autonomous mode (no previews)
  • Verify CI job still works via /test address-review-comments on a hypershift PR

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added --preview flag to utils:address-reviews command enabling interactive review mode that displays proposed actions and draft replies for approval before execution.
    • Refactored command workflow to commit locally and batch push after processing all items.
  • Chores

    • Bumped utils plugin version to 0.0.8.

bryan-cox and others added 3 commits April 9, 2026 13:06
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>
@openshift-ci
openshift-ci Bot requested review from bentito and cblecker April 9, 2026 17:06
@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 9, 2026
@coderabbitai

coderabbitai Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The utils plugin version is incremented from 0.0.7 to 0.0.8 across all plugin metadata files. A new --preview command-line flag is added to the address-reviews command, which enables interactive review mode where users can approve, edit, or skip responses to reviewer comments before posting. The control flow is refactored to defer pushing changes until after all previewed items are processed.

Changes

Cohort / File(s) Summary
Plugin Version Bump
.claude-plugin/marketplace.json, plugins/utils/.claude-plugin/plugin.json
Incremented utils plugin version from 0.0.7 to 0.0.8.
Command Signature Documentation
PLUGINS.md, docs/data.json
Updated address-reviews command signature and argument hint to include optional [--preview] flag; bumped documented version to 0.0.8.
Command Implementation Documentation
plugins/utils/commands/address-reviews.md
Added --preview CLI flag to enable interactive preview mode. Refactored control flow: defers commit pushing to after preview approval step; introduces "Step 4: Post Replies and Push" that batches reply posting followed by single push operation with explicit failure reporting.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors)

Check name Status Explanation Resolution
No Assumed Git Remote Names ❌ Error The address-reviews.md file contains hardcoded 'origin' references on lines 142, 144, 154, and 210 without first discovering the actual git remote name. Update documentation to discover the remote name using git remote -v or git branch -vv before using it in subsequent commands.
Git Push Safety Rules ❌ Error The implementation violates two critical git push safety rules: autonomous push without user confirmation and use of force push variant git push --force-with-lease. Replace force push with standard git push and add explicit user confirmation step before executing Step 4b push command.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the two main changes: implementing batch push logic and adding a preview mode to the address-reviews command.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
No Real People Names In Style References ✅ Passed No references to real people's names found in plugin commands, skill documentation, example prompts, or style references across all modified files.
No Untrusted Mcp Servers ✅ Passed The pull request does not introduce any MCP server installations from untrusted or any other sources. Changes are limited to updating utils plugin version, documenting a new flag, and refactoring internal workflow logic.
Ai-Helpers Overlap Detection ✅ Passed The address-reviews command is the only command handling PR review comment addressing; no overlapping functionality found in other commands or open PRs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

bryan-cox and others added 2 commits April 9, 2026 13:08
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>
@bryan-cox
bryan-cox force-pushed the fix/address-reviews-batch-push branch from a8c757b to 6ae6242 Compare April 9, 2026 17:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 543a2fc and 6ae6242.

📒 Files selected for processing (5)
  • .claude-plugin/marketplace.json
  • PLUGINS.md
  • docs/data.json
  • plugins/utils/.claude-plugin/plugin.json
  • plugins/utils/commands/address-reviews.md

Comment on lines +193 to +195
```
gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments/<comment_id>/replies -f body="<reply>"
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

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.

Comment on lines +194 to +197
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>"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate and read the file
find . -name "address-reviews.md" -type f 2>/dev/null | head -5

Repository: 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.md

Repository: 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 -n

Repository: 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 (where comment_id must 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_id equals the top-level comment’s id. [1]

Source


🌐 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)

  1. 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]
  1. 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]
  1. 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) with event:
    • APPROVE, REQUEST_CHANGES, COMMENT
    • If event is omitted, the review is created as PENDING (a pending review you submit later). [4]
  • GitHub Actions trigger: pull_request_review with activity types submitted, edited, dismissed (and you can check github.event.review.state). [2]
  1. 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:


🏁 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 2

Repository: 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 -n

Repository: 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 -50

Repository: 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 -n

Repository: 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 sometimes in_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/comments or GET /repos/{owner}/{repo}/issues/{issue_number}/comments.
  • Has fields like issue_url and 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 the pull_request key:
    • 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 the pull_request key. [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

  1. GitHub REST: Pull request review comments (example response includes pull_request_review_id, diff_hunk, path, etc.). [1]
  2. GitHub REST: Issue comments (example response includes issue_url; used for issues and PR conversation comments). [2]
  3. GitHub REST: Issues endpoints note PRs can be identified by the pull_request key. [3]

[1] (docs.github.com)
[2] (docs.github.com)
[3] (docs.github.com)

Citations:


🌐 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 addPullRequestReviewThreadReply mutation

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).

@muraee

muraee commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Apr 10, 2026
@openshift-ci

openshift-ci Bot commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

[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

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants