From ba82c7268f7ccf53a7fe074bfd8fc531866d7a13 Mon Sep 17 00:00:00 2001 From: Kros Dai Date: Sun, 29 Mar 2026 08:07:48 -0400 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20feat(ci):=20add=20previous=20re?= =?UTF-8?q?view=20comment=20handling=20to=20code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🔧 Handle previous claude[bot] inline comments on `synchronize` events to avoid duplicate comments on already-fixed issues - 🔧 Auto-resolve fixed comment threads via GraphQL - 🔧 Bump `--max-turns` from 5 to 10 for processing previous comments Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/code-review.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 0546e22..4361382 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -42,13 +42,34 @@ jobs: with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | + ## Handle Previous Review Comments + + Before starting your review, check for and resolve your own previous comments: + + 1. Get all previous inline review comments from claude[bot]: + `gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments --jq '[.[] | select(.user.login == "claude[bot]")]'` + 2. Get the current diff: `gh pr diff ${{ github.event.pull_request.number }}` + 3. For each previous comment: + - Read the CURRENT version of the file at the commented line + - If FIXED: reply "Fixed. {brief description}" and resolve the thread + - If STILL EXISTS: reply noting it persists, do NOT create a duplicate inline comment + - If PARTIALLY FIXED: reply explaining what remains + 4. Only create NEW inline comments for genuinely new issues not already covered. + 5. To resolve fixed comment threads: + a. Query review thread IDs via GraphQL: + `gh api graphql -f query='{ repository(owner:"${{ github.repository_owner }}", name:"${{ github.event.repository.name }}") { pullRequest(number:${{ github.event.pull_request.number }}) { reviewThreads(first:100) { nodes { id isResolved comments(first:1) { nodes { databaseId body } } } } } } }'` + b. Match each fixed comment's databaseId to find the thread node ID + c. Resolve: `gh api graphql -f query='mutation { resolveReviewThread(input:{threadId:"THREAD_NODE_ID"}) { thread { isResolved } } }'` + + ## Review Instructions + Review this pull request for code quality, correctness, and security. Analyze the diff in the context of the full codebase. Post your findings as review comments on the specific lines where issues are found. Follow the guidelines in REVIEW.md if present. claude_args: | --model opus - --max-turns 5 + --max-turns 10 --allowedTools "WebSearch,WebFetch,mcp__github_inline_comment__create_inline_comment,Bash(gh api:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr checks:*),Bash(git log:*),Bash(git blame:*),Bash(git diff:*)," env: ANTHROPIC_BASE_URL: ${{ vars.ANTHROPIC_BASE_URL }} From 8e12fe19dc4ab9b926f6dd5cc81cfa8df2ac6018 Mon Sep 17 00:00:00 2001 From: Kros Dai Date: Sun, 29 Mar 2026 08:16:23 -0400 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20fix(ci):=20address=20review?= =?UTF-8?q?=20feedback=20on=20previous-comment=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - paginate REST comment fetch and exclude reply comments (`in_reply_to_id == null`) to avoid reprocessing bot's own replies - paginate GraphQL thread lookup and fetch all comments per thread (`first:100`) for reliable `databaseId` matching - add `GH_TOKEN` env to `claude-code-action` step so `gh api` calls are authenticated Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/code-review.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 4361382..7126ad1 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -2,7 +2,7 @@ name: Code Review on: pull_request: - types: [opened, synchronize, ready_for_review] + types: [opened, ready_for_review, reopened, synchronize] workflow_call: secrets: ANTHROPIC_API_KEY: @@ -46,8 +46,8 @@ jobs: Before starting your review, check for and resolve your own previous comments: - 1. Get all previous inline review comments from claude[bot]: - `gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments --jq '[.[] | select(.user.login == "claude[bot]")]'` + 1. Get all previous top-level inline review comments from claude[bot] (exclude replies): + `gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments --paginate --jq '[.[] | select(.user.login == "claude[bot]" and .in_reply_to_id == null)]'` 2. Get the current diff: `gh pr diff ${{ github.event.pull_request.number }}` 3. For each previous comment: - Read the CURRENT version of the file at the commented line @@ -56,8 +56,8 @@ jobs: - If PARTIALLY FIXED: reply explaining what remains 4. Only create NEW inline comments for genuinely new issues not already covered. 5. To resolve fixed comment threads: - a. Query review thread IDs via GraphQL: - `gh api graphql -f query='{ repository(owner:"${{ github.repository_owner }}", name:"${{ github.event.repository.name }}") { pullRequest(number:${{ github.event.pull_request.number }}) { reviewThreads(first:100) { nodes { id isResolved comments(first:1) { nodes { databaseId body } } } } } } }'` + a. Query review thread IDs via GraphQL (paginated, all comments per thread): + `gh api graphql --paginate -f query='query($cursor:String){ repository(owner:"${{ github.repository_owner }}", name:"${{ github.event.repository.name }}") { pullRequest(number:${{ github.event.pull_request.number }}) { reviewThreads(first:100, after:$cursor) { pageInfo { hasNextPage endCursor } nodes { id isResolved comments(first:100) { nodes { databaseId body } } } } } } }'` b. Match each fixed comment's databaseId to find the thread node ID c. Resolve: `gh api graphql -f query='mutation { resolveReviewThread(input:{threadId:"THREAD_NODE_ID"}) { thread { isResolved } } }'` @@ -69,8 +69,8 @@ jobs: Follow the guidelines in REVIEW.md if present. claude_args: | --model opus - --max-turns 10 --allowedTools "WebSearch,WebFetch,mcp__github_inline_comment__create_inline_comment,Bash(gh api:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr checks:*),Bash(git log:*),Bash(git blame:*),Bash(git diff:*)," env: + GH_TOKEN: ${{ github.token }} ANTHROPIC_BASE_URL: ${{ vars.ANTHROPIC_BASE_URL }} ANTHROPIC_CUSTOM_HEADERS: '{"anthropic-beta": "context-1m-2025-08-07,interleaved-thinking-2025-05-14"}'