Skip to content

Conversation

@kpj2006
Copy link
Contributor

@kpj2006 kpj2006 commented Feb 11, 2026

Addressed Issues:

Fixes #(issue number)

Screenshots/Recordings:

Additional Notes:

Checklist

  • My code follows the project's code style and conventions
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contributing Guidelines

⚠️ AI Notice - Important!

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

  • Chores
    • Added an automated workflow to synchronize CodeRabbit review labels on pull requests. The "unresolved-code-rabbit-review" label is now automatically applied when unresolved review threads exist and removed when all are resolved.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

Walkthrough

Adds a GitHub Actions workflow that automatically synchronizes a label (unresolved-code-rabbit-review) on pull requests based on the presence of unresolved CodeRabbit review threads. The workflow queries PR review threads via GraphQL and manages label state accordingly.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow
.github/workflows/coderabbit-label-sync.yml
New workflow triggered on PR events that queries unresolved CodeRabbit review threads and automatically adds or removes the unresolved-code-rabbit-review label to keep PR state synchronized with review status.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

Typescript Lang

Suggested reviewers

  • Zahnentferner

Poem

🐰 A workflow hops into the fold,
Watching threads so they're not left cold,
Labels sync with a gentle touch,
Reviews resolved—oh, we care so much!
GitHub's garden grows more bold. 🌿✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and specifically describes the main change: adding a CodeRabbit label sync workflow for PR reviews, which matches the changeset that adds a new GitHub Actions workflow file.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

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

@github-actions github-actions bot added size/M and removed size/M labels Feb 11, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Fix all issues with AI agents
In @.github/workflows/coderabbit-label-sync.yml:
- Around line 38-50: The GraphQL query limits reviewThreads and comments
(reviewThreads(first: 100) and comments(first: 10)) so PRs with >100 threads or
>10 comments per thread can be truncated; update the query-handling to check
reviewThreads.pageInfo.hasNextPage and comments.pageInfo.hasNextPage and at
minimum log a warning when either is true, and ideally implement cursor-based
pagination to fetch additional pages (using endCursor and subsequent queries) to
fully iterate all reviewThreads and their comments before deciding label
changes.
- Around line 110-132: Wrap the GitHub Issues API calls
github.rest.issues.addLabels and github.rest.issues.removeLabel (the blocks
guarded by hasUnresolved/existingLabel) in try/catch so API failures don't abort
the workflow: on failure log a descriptive message including prNumber, the
action attempted and the caught error (use console.error or processLogger), and
do not rethrow; for removeLabel consider suppressing 404 errors (label not
found) while still logging other errors. This keeps label sync best-effort while
preserving the existing hasUnresolved/existingLabel logic.
- Around line 84-86: The workflow currently writes intermediate outputs with
core.setOutput ('has-unresolved', 'unresolved-count', 'pr-number') to pass data
to a subsequent step; instead, merge the producer and consumer into one
github-script step so you can directly call the filtering/labeling logic without
core.setOutput/steps.<...>.outputs: move the unresolvedCodeRabbitThreads
filtering and label management into the same github-script invocation (use the
existing unresolvedCodeRabbitThreads and prNumber variables directly), remove
the separate step that reads those outputs, and delete the now-unneeded
core.setOutput calls to eliminate the output-passing and injection surface.
- Around line 3-5: Add an inline comment above the "pull_request_target" trigger
documenting that using pull_request_target is intentional because the workflow
only queries PR metadata and manages labels (no checkout of PR code), note the
security risk if a checkout or other untrusted-code steps are added later
(especially for forked PRs), and optionally document any permission restrictions
(e.g., no write/contents permissions or safe token usage) to make the rationale
and constraints explicit next to the pull_request_target declaration.
- Around line 92-95: The script currently interpolates GitHub Actions outputs
directly into JS strings (prNumber, hasUnresolved, unresolvedCount), which is
insecure; instead, expose those outputs as environment variables on the step
(e.g., PR_NUMBER, HAS_UNRESOLVED, UNRESOLVED_COUNT) and read them via
process.env inside the script (parseInt(process.env.PR_NUMBER),
process.env.HAS_UNRESOLVED === 'true', parseInt(process.env.UNRESOLVED_COUNT'));
set the env either at the step level or as a sibling of script under with when
using actions/github-script@v7.
- Around line 10-11: The workflow is using the unsupported trigger name
pull_request_review_thread; replace it with supported triggers so the workflow
can run—remove pull_request_review_thread and instead rely on
pull_request_review (already present) combined with issue_comment for
comment-based thread updates, or add a schedule trigger to poll thread
resolution, or add workflow_dispatch for manual runs; update the triggers block
to use one of these supported events and ensure any logic that relied on
pull_request_review_thread is invoked from the chosen supported event handlers.

Comment on lines +3 to +5
on:
pull_request_target:
types: [opened, reopened, synchronize, edited]
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

pull_request_target runs the workflow from the base branch with write permissions — ensure this is intentional.

Using pull_request_target is appropriate here since the workflow only reads PR metadata via GraphQL and manages labels (no checkout of untrusted code). Just be aware that if someone later adds a checkout step, this becomes a significant security risk for fork-based PRs.

Consider adding a comment in the workflow to document why pull_request_target is used.

🤖 Prompt for AI Agents
In @.github/workflows/coderabbit-label-sync.yml around lines 3 - 5, Add an
inline comment above the "pull_request_target" trigger documenting that using
pull_request_target is intentional because the workflow only queries PR metadata
and manages labels (no checkout of PR code), note the security risk if a
checkout or other untrusted-code steps are added later (especially for forked
PRs), and optionally document any permission restrictions (e.g., no
write/contents permissions or safe token usage) to make the rationale and
constraints explicit next to the pull_request_target declaration.

Comment on lines +10 to +11
pull_request_review_thread:
types: [resolved, unresolved]
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

GitHub Actions pull_request_review_thread webhook event

💡 Result:

pull_request_review_thread is a GitHub webhook event that fires when there is activity on a pull request review comment thread (i.e., a diff comment “thread”), specifically when the thread is marked as resolved (action: resolved). The webhook payload includes (at least) action, pull_request, thread, and sender. [1]

It is not one of the events that can directly trigger GitHub Actions workflows (it does not appear in the “Events that trigger workflows” list). [2]

If you need an Actions workflow to react to PR review activity, you typically use pull_request_review or pull_request_review_comment (and issue_comment for non-diff PR comments), depending on what you’re targeting. [1]

Sources: [1] GitHub Docs – “Webhook events and payloads” (pull_request_review_thread) ; [2] GitHub Docs – “Events that trigger workflows” (GitHub Actions)


pull_request_review_thread is not supported as a GitHub Actions workflow trigger.

While pull_request_review_thread exists as a GitHub webhook event, it cannot trigger workflows. The workflow will never fire when review threads are resolved or unresolved, defeating this workflow's core purpose.

Use one of these alternatives instead:

  • pull_request_review (already present) combined with issue_comment, or
  • A schedule trigger to periodically poll for resolution state, or
  • workflow_dispatch for manual invocation.
🧰 Tools
🪛 actionlint (1.7.10)

[error] 10-10: unknown Webhook event "pull_request_review_thread". see https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#webhook-events for list of all Webhook event names

(events)

🤖 Prompt for AI Agents
In @.github/workflows/coderabbit-label-sync.yml around lines 10 - 11, The
workflow is using the unsupported trigger name pull_request_review_thread;
replace it with supported triggers so the workflow can run—remove
pull_request_review_thread and instead rely on pull_request_review (already
present) combined with issue_comment for comment-based thread updates, or add a
schedule trigger to poll thread resolution, or add workflow_dispatch for manual
runs; update the triggers block to use one of these supported events and ensure
any logic that relied on pull_request_review_thread is invoked from the chosen
supported event handlers.

Comment on lines +38 to +50
reviewThreads(first: 100) {
nodes {
isResolved
isOutdated
comments(first: 10) {
nodes {
author {
login
}
body
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Pagination not handled — PRs with >100 review threads will silently miss unresolved threads.

The GraphQL query fetches at most 100 threads and 10 comments per thread. For large PRs with extensive review activity, some threads will be silently skipped, potentially causing the label to be removed prematurely (false negative).

At minimum, consider checking reviewThreads.pageInfo.hasNextPage and logging a warning when results are truncated. Ideally, paginate through all threads.

🤖 Prompt for AI Agents
In @.github/workflows/coderabbit-label-sync.yml around lines 38 - 50, The
GraphQL query limits reviewThreads and comments (reviewThreads(first: 100) and
comments(first: 10)) so PRs with >100 threads or >10 comments per thread can be
truncated; update the query-handling to check reviewThreads.pageInfo.hasNextPage
and comments.pageInfo.hasNextPage and at minimum log a warning when either is
true, and ideally implement cursor-based pagination to fetch additional pages
(using endCursor and subsequent queries) to fully iterate all reviewThreads and
their comments before deciding label changes.

Comment on lines +84 to +86
core.setOutput('has-unresolved', unresolvedCodeRabbitThreads.length > 0);
core.setOutput('unresolved-count', unresolvedCodeRabbitThreads.length);
core.setOutput('pr-number', prNumber);
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider consolidating into a single step.

The outputs from step 1 are only consumed by step 2 within the same job. You could combine both steps into a single github-script step, which would eliminate the output-passing mechanism entirely (and the injection concern above). The filtering logic and label management are simple enough to coexist in one script.

🤖 Prompt for AI Agents
In @.github/workflows/coderabbit-label-sync.yml around lines 84 - 86, The
workflow currently writes intermediate outputs with core.setOutput
('has-unresolved', 'unresolved-count', 'pr-number') to pass data to a subsequent
step; instead, merge the producer and consumer into one github-script step so
you can directly call the filtering/labeling logic without
core.setOutput/steps.<...>.outputs: move the unresolvedCodeRabbitThreads
filtering and label management into the same github-script invocation (use the
existing unresolvedCodeRabbitThreads and prNumber variables directly), remove
the separate step that reads those outputs, and delete the now-unneeded
core.setOutput calls to eliminate the output-passing and injection surface.

Comment on lines +92 to +95
script: |
const prNumber = parseInt('${{ steps.check-threads.outputs.pr-number }}');
const hasUnresolved = '${{ steps.check-threads.outputs.has-unresolved }}' === 'true';
const unresolvedCount = parseInt('${{ steps.check-threads.outputs.unresolved-count }}');
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Avoid ${{ }} interpolation inside script: blocks — use environment variables instead.

Directly embedding ${{ steps.*.outputs.* }} in JavaScript strings is a known injection anti-pattern in GitHub Actions. While these particular outputs are set by your own prior step and are currently safe, this pattern is fragile and flagged by security linters. Pass values through env instead:

Proposed fix
       uses: actions/github-script@v7
       with:
         github-token: ${{ secrets.GITHUB_TOKEN }}
+        env:
+          PR_NUMBER: ${{ steps.check-threads.outputs.pr-number }}
+          HAS_UNRESOLVED: ${{ steps.check-threads.outputs.has-unresolved }}
+          UNRESOLVED_COUNT: ${{ steps.check-threads.outputs.unresolved-count }}
         script: |
-          const prNumber = parseInt('${{ steps.check-threads.outputs.pr-number }}');
-          const hasUnresolved = '${{ steps.check-threads.outputs.has-unresolved }}' === 'true';
-          const unresolvedCount = parseInt('${{ steps.check-threads.outputs.unresolved-count }}');
+          const prNumber = parseInt(process.env.PR_NUMBER);
+          const hasUnresolved = process.env.HAS_UNRESOLVED === 'true';
+          const unresolvedCount = parseInt(process.env.UNRESOLVED_COUNT);

Note: env should be a sibling of script under with, or placed at the step level. At step level:

      - name: Update unresolved-code-rabbit-review label
        uses: actions/github-script@v7
        env:
          PR_NUMBER: ${{ steps.check-threads.outputs.pr-number }}
          HAS_UNRESOLVED: ${{ steps.check-threads.outputs.has-unresolved }}
          UNRESOLVED_COUNT: ${{ steps.check-threads.outputs.unresolved-count }}
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const prNumber = parseInt(process.env.PR_NUMBER);
            const hasUnresolved = process.env.HAS_UNRESOLVED === 'true';
            const unresolvedCount = parseInt(process.env.UNRESOLVED_COUNT);
🤖 Prompt for AI Agents
In @.github/workflows/coderabbit-label-sync.yml around lines 92 - 95, The script
currently interpolates GitHub Actions outputs directly into JS strings
(prNumber, hasUnresolved, unresolvedCount), which is insecure; instead, expose
those outputs as environment variables on the step (e.g., PR_NUMBER,
HAS_UNRESOLVED, UNRESOLVED_COUNT) and read them via process.env inside the
script (parseInt(process.env.PR_NUMBER), process.env.HAS_UNRESOLVED === 'true',
parseInt(process.env.UNRESOLVED_COUNT')); set the env either at the step level
or as a sibling of script under with when using actions/github-script@v7.

Comment on lines +110 to +132
// Apply label if unresolved comments exist
if (hasUnresolved && !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 (!hasUnresolved && 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'
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

No error handling around label API calls.

If addLabels or removeLabel fails (e.g., due to a race condition where another workflow run modifies labels concurrently, or the label was already removed), the workflow will fail with an unhandled exception. Consider wrapping these calls in try/catch blocks and logging the error gracefully, since label sync is not a critical-path operation.

Also note that addLabels will auto-create the unresolved-code-rabbit-review label with a default color if it doesn't already exist in the repository. You may want to pre-create the label with a specific color/description, or add a setup step.

🤖 Prompt for AI Agents
In @.github/workflows/coderabbit-label-sync.yml around lines 110 - 132, Wrap the
GitHub Issues API calls github.rest.issues.addLabels and
github.rest.issues.removeLabel (the blocks guarded by
hasUnresolved/existingLabel) in try/catch so API failures don't abort the
workflow: on failure log a descriptive message including prNumber, the action
attempted and the caught error (use console.error or processLogger), and do not
rethrow; for removeLabel consider suppressing 404 errors (label not found) while
still logging other errors. This keeps label sync best-effort while preserving
the existing hasUnresolved/existingLabel logic.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant