mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
feat: add review thread resolution to pr-fixer mode via GitHub GraphQL API
Updated the pr-fixer mode rules to resolve review threads on GitHub after addressing review feedback, instead of only checking off internal checkboxes. This uses the GitHub GraphQL API resolveReviewThread mutation to mark threads as resolved, providing clear signal to reviewers that their feedback was acted on. Changes across all 5 rule files: - 1_workflow.xml: Added resolve-threads phase and completion criterion - 2_best_practices.xml: Added principle and quality checklist item - 3_common_patterns.xml: Added 3 new patterns for fetching/resolving threads - 4_tool_usage.xml: Added gh api graphql tool guidance and CLI reference - 5_examples.xml: Added thread resolution steps to example workflow
This commit is contained in:
parent
12cddc9697
commit
bf34fa4464
5 changed files with 206 additions and 0 deletions
|
|
@ -55,6 +55,16 @@
|
|||
</steps>
|
||||
</phase>
|
||||
|
||||
<phase name="resolve-threads">
|
||||
<description>After pushing fixes, resolve the review threads on GitHub that have been addressed. This provides clear signal to reviewers that their feedback was acted on.</description>
|
||||
<steps>
|
||||
<step>Fetch all review threads for the PR using the GraphQL API: 'gh api graphql' with the pullRequest.reviewThreads query.</step>
|
||||
<step>For each unresolved thread, determine if the corresponding feedback has been addressed by the code changes just pushed.</step>
|
||||
<step>Resolve each addressed thread using the GraphQL 'resolveReviewThread' mutation with the thread's node ID.</step>
|
||||
<step>Leave threads unresolved if they represent open questions, future work, or feedback that was intentionally not addressed.</step>
|
||||
</steps>
|
||||
</phase>
|
||||
|
||||
<phase name="validation">
|
||||
<description>Verify that the pushed changes resolve the issues.</description>
|
||||
<steps>
|
||||
|
|
@ -68,6 +78,7 @@
|
|||
|
||||
<completion_criteria>
|
||||
<criterion>All actionable review comments have been addressed.</criterion>
|
||||
<criterion>Addressed review threads have been resolved on GitHub using the GraphQL API.</criterion>
|
||||
<criterion>All tests are passing.</criterion>
|
||||
<criterion>The PR is free of merge conflicts.</criterion>
|
||||
<criterion>All required translations have been completed and committed (if changes affect user-facing content).</criterion>
|
||||
|
|
|
|||
|
|
@ -37,6 +37,16 @@
|
|||
<item>Verify .gitignore is properly configured</item>
|
||||
</checklist>
|
||||
</principle>
|
||||
<principle priority="high">
|
||||
<name>Resolve Review Threads, Don't Just Check Boxes</name>
|
||||
<description>After addressing review feedback and pushing changes, resolve the corresponding review threads on GitHub using the GraphQL API. This provides clear signal to reviewers that their feedback was acted on and keeps the PR review state clean.</description>
|
||||
<rationale>Checking off internal checklists is not visible to reviewers. Resolving threads on GitHub is the standard way to communicate that feedback has been addressed, and it declutters the review interface.</rationale>
|
||||
<example>
|
||||
<scenario>Review comment asking to rename a variable was addressed</scenario>
|
||||
<good>Fetch review threads via GraphQL, find the matching thread, resolve it with the resolveReviewThread mutation</good>
|
||||
<bad>Only check off an internal checkbox or leave a reply comment without resolving the thread</bad>
|
||||
</example>
|
||||
</principle>
|
||||
</general_principles>
|
||||
|
||||
<code_conventions>
|
||||
|
|
@ -67,6 +77,7 @@ This ensures consistent and intelligent conflict resolution across all PRs.
|
|||
<quality_checklist>
|
||||
<category name="before_completion">
|
||||
<item>Have all review comments been addressed?</item>
|
||||
<item>Have addressed review threads been resolved on GitHub via the GraphQL API?</item>
|
||||
<item>Are all CI/CD checks passing?</item>
|
||||
<item>Is the PR free of merge conflicts?</item>
|
||||
<item>Have the changes been tested locally?</item>
|
||||
|
|
|
|||
|
|
@ -106,6 +106,92 @@
|
|||
<command tool="git">git commit -m "<commit_message>"</command>
|
||||
</template>
|
||||
</pattern>
|
||||
<pattern name="fetch_review_threads">
|
||||
<usage>Fetch all review threads for a PR using the GitHub GraphQL API. This returns each thread's node ID, resolution status, and the first comment's body/path/line for context.</usage>
|
||||
<template>
|
||||
<command tool="gh"><![CDATA[gh api graphql -f query='
|
||||
query($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
reviewThreads(first: 100) {
|
||||
nodes {
|
||||
id
|
||||
isResolved
|
||||
isOutdated
|
||||
comments(first: 1) {
|
||||
nodes {
|
||||
body
|
||||
path
|
||||
line
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' -f owner=<owner> -f repo=<repo> -F number=<pr_number>]]></command>
|
||||
<comment>Parse the JSON output to get each thread's id (node ID) and isResolved status.</comment>
|
||||
<comment>Only threads where isResolved is false need to be resolved.</comment>
|
||||
</template>
|
||||
</pattern>
|
||||
|
||||
<pattern name="resolve_review_thread">
|
||||
<usage>Resolve a single review thread on GitHub using its node ID via the GraphQL API. Use this after addressing the feedback in the thread.</usage>
|
||||
<template>
|
||||
<command tool="gh"><![CDATA[gh api graphql -f query='
|
||||
mutation($threadId: ID!) {
|
||||
resolveReviewThread(input: {threadId: $threadId}) {
|
||||
thread {
|
||||
id
|
||||
isResolved
|
||||
}
|
||||
}
|
||||
}' -f threadId=<thread_node_id>]]></command>
|
||||
<comment>Replace thread_node_id with the actual node ID from the fetch_review_threads query.</comment>
|
||||
<comment>Only resolve threads whose feedback has actually been addressed in code.</comment>
|
||||
</template>
|
||||
</pattern>
|
||||
|
||||
<pattern name="resolve_all_addressed_threads">
|
||||
<usage>End-to-end pattern: fetch all unresolved review threads, then resolve each one that was addressed.</usage>
|
||||
<template>
|
||||
<comment>Step 1: Fetch all review threads</comment>
|
||||
<command tool="gh"><![CDATA[gh api graphql -f query='
|
||||
query($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
reviewThreads(first: 100) {
|
||||
nodes {
|
||||
id
|
||||
isResolved
|
||||
isOutdated
|
||||
comments(first: 1) {
|
||||
nodes {
|
||||
body
|
||||
path
|
||||
line
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' -f owner=<owner> -f repo=<repo> -F number=<pr_number>]]></command>
|
||||
<comment>Step 2: For each unresolved thread (isResolved: false), check if the feedback was addressed</comment>
|
||||
<comment>Step 3: Resolve each addressed thread individually</comment>
|
||||
<command tool="gh"><![CDATA[gh api graphql -f query='
|
||||
mutation($threadId: ID!) {
|
||||
resolveReviewThread(input: {threadId: $threadId}) {
|
||||
thread {
|
||||
id
|
||||
isResolved
|
||||
}
|
||||
}
|
||||
}' -f threadId=<thread_node_id>]]></command>
|
||||
<comment>Repeat step 3 for each addressed thread. Do NOT resolve threads for open questions or unaddressed feedback.</comment>
|
||||
</template>
|
||||
</pattern>
|
||||
|
||||
<pattern name="safe_file_staging">
|
||||
<usage>Safely stage files for commit while avoiding temporary files and respecting .gitignore.</usage>
|
||||
<template>
|
||||
|
|
|
|||
|
|
@ -81,6 +81,50 @@
|
|||
</best_practices>
|
||||
</tool>
|
||||
|
||||
<tool name="gh api graphql (resolve review threads)">
|
||||
<best_practices>
|
||||
<practice>After pushing code changes that address review feedback, use the GraphQL API to resolve the corresponding review threads on GitHub.</practice>
|
||||
<practice>First fetch all review threads: use the pullRequest.reviewThreads query to get each thread's node ID, isResolved status, and the first comment for context.</practice>
|
||||
<practice>Only resolve threads where the feedback has actually been addressed in the pushed code changes. Do not resolve threads for open questions, future work items, or feedback that was intentionally skipped.</practice>
|
||||
<practice>Resolve threads one at a time using the resolveReviewThread mutation with the thread's node ID.</practice>
|
||||
<practice>If a thread is already resolved (isResolved: true) or outdated (isOutdated: true), skip it.</practice>
|
||||
</best_practices>
|
||||
<fetch_threads_query><![CDATA[
|
||||
gh api graphql -f query='
|
||||
query($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
reviewThreads(first: 100) {
|
||||
nodes {
|
||||
id
|
||||
isResolved
|
||||
isOutdated
|
||||
comments(first: 1) {
|
||||
nodes {
|
||||
body
|
||||
path
|
||||
line
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' -f owner=[owner] -f repo=[repo] -F number=[pr_number]
|
||||
]]></fetch_threads_query>
|
||||
<resolve_thread_mutation><![CDATA[
|
||||
gh api graphql -f query='
|
||||
mutation($threadId: ID!) {
|
||||
resolveReviewThread(input: {threadId: $threadId}) {
|
||||
thread {
|
||||
id
|
||||
isResolved
|
||||
}
|
||||
}
|
||||
}' -f threadId=[thread_node_id]
|
||||
]]></resolve_thread_mutation>
|
||||
</tool>
|
||||
|
||||
<tool name="ask_followup_question">
|
||||
<best_practices>
|
||||
<practice>After analyzing all the problems (reviews, tests, conflicts), present a summary to the user.</practice>
|
||||
|
|
@ -152,5 +196,10 @@ Please ensure all supported languages (ca, de, es, fr, hi, id, it, ja, ko, nl, p
|
|||
<command>gh run view [RUN_ID] --repo [owner]/[repo] --log-failed</command>
|
||||
<command>gh workflow view [WORKFLOW_NAME] --repo [owner]/[repo]</command>
|
||||
</command_group>
|
||||
|
||||
<command_group name="review_thread_operations">
|
||||
<command>gh api graphql -f query='query { repository(owner:"[owner]", name:"[repo]") { pullRequest(number:[PR_NUMBER]) { reviewThreads(first:100) { nodes { id isResolved isOutdated comments(first:1) { nodes { body path line } } } } } } }'</command>
|
||||
<command>gh api graphql -f query='mutation { resolveReviewThread(input:{threadId:"[THREAD_NODE_ID]"}) { thread { id isResolved } } }'</command>
|
||||
</command_group>
|
||||
</github_cli_reference>
|
||||
</tool_usage_guide>
|
||||
|
|
@ -81,12 +81,61 @@
|
|||
</tool_use>
|
||||
<analysis>Monitor checks continuously until all complete. The --watch flag provides real-time updates as check statuses change.</analysis>
|
||||
</step>
|
||||
|
||||
<step number="7">
|
||||
<description>Fetch all review threads to find unresolved ones that were addressed.</description>
|
||||
<tool_use>
|
||||
<execute_command>
|
||||
<command><![CDATA[gh api graphql -f query='
|
||||
query($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
pullRequest(number: $number) {
|
||||
reviewThreads(first: 100) {
|
||||
nodes {
|
||||
id
|
||||
isResolved
|
||||
isOutdated
|
||||
comments(first: 1) {
|
||||
nodes {
|
||||
body
|
||||
path
|
||||
line
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}' -f owner=RooCodeInc -f repo=Roo-Code -F number=4365]]></command>
|
||||
</execute_command>
|
||||
</tool_use>
|
||||
<analysis>Parse the output to identify unresolved threads. Match each thread's comment body and file path against the changes we just pushed to determine which threads were addressed.</analysis>
|
||||
</step>
|
||||
|
||||
<step number="8">
|
||||
<description>Resolve each addressed review thread using the GraphQL mutation.</description>
|
||||
<tool_use>
|
||||
<execute_command>
|
||||
<command><![CDATA[gh api graphql -f query='
|
||||
mutation($threadId: ID!) {
|
||||
resolveReviewThread(input: {threadId: $threadId}) {
|
||||
thread {
|
||||
id
|
||||
isResolved
|
||||
}
|
||||
}
|
||||
}' -f threadId=PRT_kwDOExample123]]></command>
|
||||
</execute_command>
|
||||
</tool_use>
|
||||
<analysis>Repeat for each thread that was addressed. Only resolve threads where the feedback was acted on. Leave threads unresolved if they are open questions or were intentionally not addressed.</analysis>
|
||||
</step>
|
||||
</workflow>
|
||||
|
||||
<key_takeaways>
|
||||
<takeaway>Always gather all information before proposing a solution.</takeaway>
|
||||
<takeaway>Use the GitHub CLI to get a complete picture of the PR's status.</takeaway>
|
||||
<takeaway>The --watch flag on gh pr checks provides real-time monitoring of CI status.</takeaway>
|
||||
<takeaway>After addressing review feedback, resolve the corresponding review threads on GitHub using the GraphQL API instead of just checking off checkboxes.</takeaway>
|
||||
</key_takeaways>
|
||||
</example>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue