Skip to content

feat: add useGeminiReview hook with comment cleanup#189

Draft
rm-hull wants to merge 10 commits into
mainfrom
feat/hide-existing-gemini-reviews
Draft

feat: add useGeminiReview hook with comment cleanup#189
rm-hull wants to merge 10 commits into
mainfrom
feat/hide-existing-gemini-reviews

Conversation

@rm-hull

@rm-hull rm-hull commented Dec 30, 2025

Copy link
Copy Markdown
Owner

Introduces a specialized hook to handle Gemini code reviews. This ensures a cleaner pull request timeline by removing previous gemini-code-assist comments before posting a new review request.

  • Encapsulates the review logic away from the button component.
  • Automatically deletes existing assistant comments.
  • Invalidates the open-prs query state upon successful completion.
sequenceDiagram
    participant UI as GeminiReviewButton
    participant Hook as useGeminiReview
    participant API as GitHub API
    UI->>Hook: mutate()
    Hook->>API: listComments()
    API-->>Hook: comments
    Note over Hook: Filter "gemini-code-assist" comments
    loop Each existing comment
        Hook->>API: deleteComment()
    end
    Hook->>API: createComment("/gemini review")
    Hook->>Hook: invalidate open-prs
Loading

Introduces a specialized hook to handle Gemini code reviews. This
ensures a cleaner pull request timeline by removing previous
**gemini-code-assist** comments before posting a new review request.

*   Encapsulates the review logic away from the button component.
*   Automatically deletes existing assistant comments.
*   Invalidates the `open-prs` query state upon successful completion.

```mermaid
sequenceDiagram
    participant UI as GeminiReviewButton
    participant Hook as useGeminiReview
    participant API as GitHub API
    UI->>Hook: mutate()
    Hook->>API: listComments()
    API-->>Hook: comments
    Note over Hook: Filter "gemini-code-assist" comments
    loop Each existing comment
        Hook->>API: deleteComment()
    end
    Hook->>API: createComment("/gemini review")
    Hook->>Hook: invalidate open-prs
```
gemini-code-assist[bot]

This comment was marked as outdated.

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@coveralls

coveralls commented Dec 30, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 23121634691

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 52.381%

Totals Coverage Status
Change from base Build 23051549628: 0.0%
Covered Lines: 30
Relevant Lines: 59

💛 - Coveralls

Extract hardcoded strings for the Gemini user login and the review
command into named constants to improve maintainability.
gemini-code-assist[bot]

This comment was marked as outdated.

Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
gemini-code-assist[bot]

This comment was marked as outdated.

Update the `GEMINI_USER_LOGIN` constant to include the `[bot]` suffix
to match GitHub's bot naming convention. This ensures the hook
correctly filters and deletes previous review comments.
gemini-code-assist[bot]

This comment was marked as outdated.

gemini-code-assist[bot]

This comment was marked as outdated.

Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
gemini-code-assist[bot]

This comment was marked as outdated.

rm-hull and others added 2 commits December 30, 2025 21:49
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
The hook now identifies and removes review comments created by the
Gemini bot in addition to standard issue comments. This ensures a
cleaner PR state by removing all previous automated feedback before
a new review cycle begins.

```mermaid
graph TD
    Start[Start Cleanup] --> GetIssue[Fetch Issue Comments]
    Start --> GetReview[Fetch Review Comments]
    GetIssue --> FilterIssue[Filter Gemini User]
    GetReview --> FilterReview[Filter Gemini User]
    FilterIssue --> DeleteIssue[Delete Issue Comments]
    FilterReview --> DeleteReview[Delete Review Comments]
```
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
Repository owner deleted a comment from gemini-code-assist Bot Dec 30, 2025
@rm-hull

rm-hull commented Dec 30, 2025

Copy link
Copy Markdown
Owner Author

/gemini review

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a new useGeminiReview hook, which is a great improvement as it encapsulates the logic for handling Gemini code reviews and cleans up the component code. The implementation is solid, but I've identified a couple of opportunities to improve performance by parallelizing API calls within the new hook. My suggestions aim to make the process of cleaning up old comments and fetching data more efficient.

Comment on lines +19 to +35
const comments = await octokit.paginate(octokit.issues.listComments, {
owner,
repo,
issue_number: pull_number,
per_page: 100,
});

const geminiComments = comments.filter((c) => c.user?.login === GEMINI_USER_LOGIN);

const reviewComments = await octokit.paginate(octokit.pulls.listReviewComments, {
owner,
repo,
pull_number,
per_page: 100,
});

const geminiReviewComments = reviewComments.filter((c) => c.user?.login === GEMINI_USER_LOGIN);

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.

medium

The two paginate calls to fetch issue comments and review comments are executed sequentially. Since they are independent, you can run them in parallel using Promise.all to improve performance by reducing the total wait time for data fetching.

Suggested change
const comments = await octokit.paginate(octokit.issues.listComments, {
owner,
repo,
issue_number: pull_number,
per_page: 100,
});
const geminiComments = comments.filter((c) => c.user?.login === GEMINI_USER_LOGIN);
const reviewComments = await octokit.paginate(octokit.pulls.listReviewComments, {
owner,
repo,
pull_number,
per_page: 100,
});
const geminiReviewComments = reviewComments.filter((c) => c.user?.login === GEMINI_USER_LOGIN);
const [comments, reviewComments] = await Promise.all([
octokit.paginate(octokit.issues.listComments, {
owner,
repo,
issue_number: pull_number,
per_page: 100,
}),
octokit.paginate(octokit.pulls.listReviewComments, {
owner,
repo,
pull_number,
per_page: 100,
}),
]);
const geminiComments = comments.filter((c) => c.user?.login === GEMINI_USER_LOGIN);
const geminiReviewComments = reviewComments.filter((c) => c.user?.login === GEMINI_USER_LOGIN);

Comment on lines +37 to +51
for (const comment of geminiComments) {
try {
await octokit.issues.deleteComment({ owner, repo, comment_id: comment.id });
} catch (e) {
console.error(`Failed to delete issue comment ${comment.id}`, e);
}
}

for (const comment of geminiReviewComments) {
try {
await octokit.pulls.deleteReviewComment({ owner, repo, comment_id: comment.id });
} catch (e) {
console.error(`Failed to delete review comment ${comment.id}`, e);
}
}

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.

medium

The loops for deleting comments run sequentially, which can be slow if there are many comments to delete. You can significantly improve performance by running these deletion requests in parallel using Promise.all. This also makes the code more concise and handles errors for individual deletions gracefully without needing explicit try...catch blocks inside loops.

      const deletionPromises = [
        ...geminiComments.map((comment) =>
          octokit.issues.deleteComment({ owner, repo, comment_id: comment.id }).catch((e) => {
            console.error(`Failed to delete issue comment ${comment.id}`, e);
          }),
        ),
        ...geminiReviewComments.map((comment) =>
          octokit.pulls.deleteReviewComment({ owner, repo, comment_id: comment.id }).catch((e) => {
            console.error(`Failed to delete review comment ${comment.id}`, e);
          }),
        ),
      ];

      await Promise.all(deletionPromises);

@rm-hull rm-hull marked this pull request as draft March 10, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants