-
Notifications
You must be signed in to change notification settings - Fork 10
feat: add CodeRabbit review status label handling to PR sync workflow #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds a new workflow step that queries CodeRabbit review threads via GitHub GraphQL API, filters for unresolved threads containing CodeRabbit comments, and automatically updates the "unresolved-code-rabbit-review" label on pull requests accordingly. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In @.github/workflows/sync-pr-labels.yml:
- Around line 330-349: The GraphQL query currently caps reviewThreads(first:
100) and comments(first: 20) which can silently truncate data; update the query
and fetching logic around the variable/query string named "query" to implement
pagination for reviewThreads and comments using pageInfo { hasNextPage endCursor
} and cursors (e.g., after) to iterate until hasNextPage is false, or if you
prefer the minimal change add a check after each fetch: if the returned number
of reviewThreads equals 100 or any comments array length equals 20, emit a
warning log indicating potential truncation; make changes where the query string
is built and where results are consumed (look for usage of "reviewThreads" and
"comments" in the request/response handling) to either loop with cursors or log
the warning when limits are hit.
- Around line 317-424: The "Check CodeRabbit review status" step runs too early
because it only triggers on pull_request events; update the workflow triggers to
include pull_request_review and/or pull_request_review_comment so review threads
exist when this step runs (or move this step into a separate workflow triggered
by those events). Ensure the step name "Check CodeRabbit review status" and
logic using prNumber, threads, unresolvedCodeRabbitThreads, and
hasUnresolvedComments remain unchanged; add the additional events to the
workflow's on: section (or create a new workflow file that listens to
pull_request_review and pull_request_review_comment and copies this step) so
label application/removal occurs after CodeRabbit posts reviews.
- Around line 421-423: The workflow step currently calls core.setFailed inside
the catch block which aborts the job and skips the Summary step; change the
error handling to match the rest of the file by replacing
core.setFailed(error.message) with a non-fatal logging call (e.g., console.log
or core.warning) so the job continues, or if you intentionally want to record a
failure but not block downstream steps, add continue-on-error: true to the
"Check CodeRabbit review status" step definition; update the catch block around
core.setFailed to use the chosen approach and ensure the log still includes
error.message.
- Around line 414-419: Remove the redundant no-op branch that logs "Label
already in correct state. No changes needed." — specifically delete the else
block that checks (hasUnresolvedComments && existingLabel) ||
(!hasUnresolvedComments && !existingLabel) and its console.log, leaving only the
add/remove branches that already log actions; ensure surrounding conditional
logic and indentation remain intact so behavior is unchanged.
- Around line 362-369: The filter for unresolvedCodeRabbitThreads currently
matches any login containing "coderabbit"; change it to perform a strict
equality on the normalized login (e.g., comment.author.login.toLowerCase() ===
"coderabbitai") so only the bot identity from .coderabbit.yaml is matched; keep
the existing null checks for comment.author and comment.author.login and update
the predicate used in threads.filter/unresolvedCodeRabbitThreads accordingly.
|
|
||
| # STEP 5: CodeRabbit review status labels | ||
| - name: Check CodeRabbit review status | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| script: | | ||
| const prNumber = context.payload.pull_request.number; | ||
|
|
||
| try { | ||
| console.log(`Checking CodeRabbit review threads for PR #${prNumber}`); | ||
|
|
||
| // GraphQL query to fetch review threads and resolution status | ||
| const query = ` | ||
| query($owner: String!, $repo: String!, $prNumber: Int!) { | ||
| repository(owner: $owner, name: $repo) { | ||
| pullRequest(number: $prNumber) { | ||
| reviewThreads(first: 100) { | ||
| nodes { | ||
| isResolved | ||
| comments(first: 20) { | ||
| nodes { | ||
| author { | ||
| login | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| const result = await github.graphql(query, { | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| prNumber: prNumber | ||
| }); | ||
|
|
||
| const threads = result.repository.pullRequest.reviewThreads.nodes; | ||
|
|
||
| console.log(`Total review threads found: ${threads.length}`); | ||
|
|
||
| // Filter unresolved CodeRabbit threads | ||
| const unresolvedCodeRabbitThreads = threads.filter(thread => | ||
| !thread.isResolved && | ||
| thread.comments.nodes.some(comment => | ||
| comment.author && | ||
| comment.author.login && | ||
| comment.author.login.toLowerCase().includes("coderabbit") | ||
| ) | ||
| ); | ||
|
|
||
| const hasUnresolvedComments = unresolvedCodeRabbitThreads.length > 0; | ||
|
|
||
| console.log(`Unresolved CodeRabbit threads: ${unresolvedCodeRabbitThreads.length}`); | ||
|
|
||
| // Get current labels | ||
| const currentLabels = await github.rest.issues.listLabelsOnIssue({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber | ||
| }); | ||
|
|
||
| const existingLabel = currentLabels.data.find( | ||
| label => label.name === "unresolved-code-rabbit-review" | ||
| ); | ||
|
|
||
| // Apply label if unresolved comments exist | ||
| if (hasUnresolvedComments && !existingLabel) { | ||
|
|
||
| console.log("Applying unresolved-code-rabbit-review label"); | ||
|
|
||
| await github.rest.issues.addLabels({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| labels: ["unresolved-code-rabbit-review"] | ||
| }); | ||
|
|
||
| } | ||
|
|
||
| // Remove label if all comments resolved | ||
| if (!hasUnresolvedComments && existingLabel) { | ||
|
|
||
| console.log("Removing unresolved-code-rabbit-review label"); | ||
|
|
||
| await github.rest.issues.removeLabel({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| name: "unresolved-code-rabbit-review" | ||
| }); | ||
|
|
||
| } | ||
|
|
||
| if ( | ||
| (hasUnresolvedComments && existingLabel) || | ||
| (!hasUnresolvedComments && !existingLabel) | ||
| ) { | ||
| console.log("Label already in correct state. No changes needed."); | ||
| } | ||
|
|
||
| } catch (error) { | ||
| console.log(`Error checking CodeRabbit review status: ${error.message}`); | ||
| core.setFailed(error.message); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Workflow triggers are unlikely to capture CodeRabbit review state changes.
This step runs on opened, reopened, synchronize, and edited events. CodeRabbit posts its reviews asynchronously after those events fire, so at execution time the review threads typically won't exist yet (or won't reflect the latest state). To make this step useful, consider adding pull_request_review and/or pull_request_review_comment to the workflow triggers, or running this step on a separate workflow with the appropriate triggers.
🤖 Prompt for AI Agents
In @.github/workflows/sync-pr-labels.yml around lines 317 - 424, The "Check
CodeRabbit review status" step runs too early because it only triggers on
pull_request events; update the workflow triggers to include pull_request_review
and/or pull_request_review_comment so review threads exist when this step runs
(or move this step into a separate workflow triggered by those events). Ensure
the step name "Check CodeRabbit review status" and logic using prNumber,
threads, unresolvedCodeRabbitThreads, and hasUnresolvedComments remain
unchanged; add the additional events to the workflow's on: section (or create a
new workflow file that listens to pull_request_review and
pull_request_review_comment and copies this step) so label application/removal
occurs after CodeRabbit posts reviews.
| const unresolvedCodeRabbitThreads = threads.filter(thread => | ||
| !thread.isResolved && | ||
| thread.comments.nodes.some(comment => | ||
| comment.author && | ||
| comment.author.login && | ||
| comment.author.login.toLowerCase().includes("coderabbit") | ||
| ) | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, verify the file exists and check the code at the specified lines
git ls-files | grep -i "sync-pr-labels.yml"Repository: AOSSIE-Org/Template-Repo
Length of output: 104
🏁 Script executed:
# Search for CodeRabbit bot login patterns in the repository
rg "coderabbit" --ignore-case -i -A 2 -B 2 | head -100Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Check for any environment variables or config that might define the bot login
rg "bot.*login\|login.*bot" --ignore-case -A 2 | head -50Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Read the file to verify the code at lines 362-369
wc -l .github/workflows/sync-pr-labels.ymlRepository: AOSSIE-Org/Template-Repo
Length of output: 108
🏁 Script executed:
# Read the specific lines mentioned in the review
sed -n '355,375p' .github/workflows/sync-pr-labels.ymlRepository: AOSSIE-Org/Template-Repo
Length of output: 877
🏁 Script executed:
# Look for any bot configuration or comments in the entire file
grep -n "coderabbit\|bot\|author" .github/workflows/sync-pr-labels.yml | head -20Repository: AOSSIE-Org/Template-Repo
Length of output: 371
🏁 Script executed:
# Look for any CodeRabbit configuration or references in the repository
fd "README\|CONTRIBUTING\|\.md$" --type f | xargs rg -i "coderabbit" 2>/dev/null | head -20Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Check for any environment variables or config files that might define the bot login
find . -name "*.yml" -o -name "*.yaml" -o -name "*.json" | grep -v node_modules | xargs grep -l "coderabbit" 2>/dev/nullRepository: AOSSIE-Org/Template-Repo
Length of output: 125
🏁 Script executed:
# Check if there's any other reference to "coderabbitai" in the codebase
rg "coderabbitai" --ignore-caseRepository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Check the CodeRabbit configuration file
cat .coderabbit.yamlRepository: AOSSIE-Org/Template-Repo
Length of output: 8526
🏁 Script executed:
# Search for any bot login or username in all YAML files
rg "login|username|bot" --type yaml -i -A 2Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Search the entire workflow file for bot or user references
grep -n "bot\|user\|login" .github/workflows/sync-pr-labels.yml | head -30Repository: AOSSIE-Org/Template-Repo
Length of output: 454
🏁 Script executed:
# Read the entire workflow file to look for any comments or context about CodeRabbit
cat .github/workflows/sync-pr-labels.yml | grep -i "coderabbit\|bot\|author" -B 3 -A 3Repository: AOSSIE-Org/Template-Repo
Length of output: 3241
🏁 Script executed:
# Look for any GitHub Actions that might reference the CodeRabbit bot
grep -n "uses:\|run:" .github/workflows/sync-pr-labels.yml | head -20Repository: AOSSIE-Org/Template-Repo
Length of output: 493
🏁 Script executed:
# Search for any credentials or secrets related to CodeRabbit
rg "secret\|token\|coderabbit" --type yaml -iRepository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Search for any other references to the bot login to confirm it's "coderabbitai"
rg "coderabbitai\|@coderabbit" --type yaml -B 2 -A 2Repository: AOSSIE-Org/Template-Repo
Length of output: 50
🏁 Script executed:
# Check if there are any comments or documentation about the bot login
grep -r "coderabbit" --include="*.md" --include="*.txt" 2>/dev/nullRepository: AOSSIE-Org/Template-Repo
Length of output: 50
Use strict equality check for CodeRabbit bot login matching.
comment.author.login.toLowerCase().includes("coderabbit") will match any GitHub user whose login contains the substring "coderabbit" (e.g., notcoderabbitbot). The bot identity is coderabbitai per .coderabbit.yaml configuration. Replace with a strict equality check.
Proposed fix
const unresolvedCodeRabbitThreads = threads.filter(thread =>
!thread.isResolved &&
thread.comments.nodes.some(comment =>
comment.author &&
- comment.author.login &&
- comment.author.login.toLowerCase().includes("coderabbit")
+ comment.author.login === "coderabbitai"
)
);🤖 Prompt for AI Agents
In @.github/workflows/sync-pr-labels.yml around lines 362 - 369, The filter for
unresolvedCodeRabbitThreads currently matches any login containing "coderabbit";
change it to perform a strict equality on the normalized login (e.g.,
comment.author.login.toLowerCase() === "coderabbitai") so only the bot identity
from .coderabbit.yaml is matched; keep the existing null checks for
comment.author and comment.author.login and update the predicate used in
threads.filter/unresolvedCodeRabbitThreads accordingly.
| if ( | ||
| (hasUnresolvedComments && existingLabel) || | ||
| (!hasUnresolvedComments && !existingLabel) | ||
| ) { | ||
| console.log("Label already in correct state. No changes needed."); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Redundant no-op branch adds noise without value.
The "label already in correct state" log is the else-case of the two preceding if blocks and adds no actionable information. Consider removing it to keep the logic concise.
Proposed simplification
- if (
- (hasUnresolvedComments && existingLabel) ||
- (!hasUnresolvedComments && !existingLabel)
- ) {
- console.log("Label already in correct state. No changes needed.");
- }
+ if (!hasUnresolvedComments && !existingLabel) {
+ console.log("No unresolved CodeRabbit threads. Label not present.");
+ }Or simply remove the block entirely—the add/remove branches already log their actions.
🤖 Prompt for AI Agents
In @.github/workflows/sync-pr-labels.yml around lines 414 - 419, Remove the
redundant no-op branch that logs "Label already in correct state. No changes
needed." — specifically delete the else block that checks (hasUnresolvedComments
&& existingLabel) || (!hasUnresolvedComments && !existingLabel) and its
console.log, leaving only the add/remove branches that already log actions;
ensure surrounding conditional logic and indentation remain intact so behavior
is unchanged.
| } catch (error) { | ||
| console.log(`Error checking CodeRabbit review status: ${error.message}`); | ||
| core.setFailed(error.message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
core.setFailed will abort the job and skip the Summary step.
Every other step in this workflow logs errors with console.log and continues. Using core.setFailed here is inconsistent and will prevent the final summary step from executing. Either use console.log/core.warning to stay consistent, or add continue-on-error: true to this step if you want the failure recorded but non-blocking.
Option A: match existing error-handling pattern
} catch (error) {
console.log(`Error checking CodeRabbit review status: ${error.message}`);
- core.setFailed(error.message);
}Option B: keep setFailed but don't block downstream steps
Add continue-on-error: true to the step definition:
- name: Check CodeRabbit review status
continue-on-error: true
uses: actions/github-script@v7📝 Committable suggestion
‼️ 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.
| } catch (error) { | |
| console.log(`Error checking CodeRabbit review status: ${error.message}`); | |
| core.setFailed(error.message); | |
| } catch (error) { | |
| console.log(`Error checking CodeRabbit review status: ${error.message}`); | |
| } |
🤖 Prompt for AI Agents
In @.github/workflows/sync-pr-labels.yml around lines 421 - 423, The workflow
step currently calls core.setFailed inside the catch block which aborts the job
and skips the Summary step; change the error handling to match the rest of the
file by replacing core.setFailed(error.message) with a non-fatal logging call
(e.g., console.log or core.warning) so the job continues, or if you
intentionally want to record a failure but not block downstream steps, add
continue-on-error: true to the "Check CodeRabbit review status" step definition;
update the catch block around core.setFailed to use the chosen approach and
ensure the log still includes error.message.
Addressed Issues:
Fixes #(issue number)
Screenshots/Recordings:
Additional Notes:
Checklist
We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.
Summary by CodeRabbit