ci: PR review automation (CodeRabbit approval + maintainer automerge)#12462
Conversation
Add a workflow that fires on pull_request_review and, when CodeRabbit submits an approving review, applies the informational "reviewed: coderabbit" label and (if a DISCORD_WEBHOOK secret is configured) posts a notice to Discord. PR fields reach the steps through the environment rather than script interpolation, so an attacker-controlled PR title cannot inject shell commands. The Discord step is skipped when the webhook secret is unset.
Code Review by Qodo
1. Stale automerge label
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughA new GitHub Actions workflow ( ChangesPR Review Automation Workflow
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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 |
PR Summary by QodoCI: label PRs and optionally notify Discord on CodeRabbit approval WalkthroughsDescription• Add a workflow triggered by submitted PR reviews. • When CodeRabbit approves, apply the "reviewed: coderabbit" label. • Optionally post an approval notice to Discord when DISCORD_WEBHOOK is set. Diagramgraph TD
A["pull_request_review submitted"] --> B{"Approved by CodeRabbit?"} --> C["Step: add label"] --> D["GitHub PR metadata"]
B --> E{"DISCORD_WEBHOOK set?"} --> F["Step: Discord notify"] --> G["Discord webhook"]
C --> H["GitHub API (labels)"]
subgraph Legend
direction LR
_evt([Event]) ~~~ _dec{Decision} ~~~ _job[Step] ~~~ _ext[[External]]
end
High-Level AssessmentThe following are alternative approaches to this PR: 1. Use actions/github-script instead of gh CLI
2. Use a dedicated Discord notification action
Recommendation: The current approach is solid for a security-sensitive trigger: it avoids checkout, narrows permissions, gates on bot+approval, and builds JSON safely with jq. If maintainers prefer fewer shell dependencies, switching the label step to actions/github-script is the most meaningful alternative; otherwise, keep this implementation. File ChangesOther (1)
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/coderabbit-approval-notify.yml (1)
40-40: ⚡ Quick winAdd timeout/retry bounds to the Discord webhook call.
curl -fsScan still fail on transient network faults (or wait too long). Add connect/overall timeouts and retries so this step is more resilient.Suggested patch
- curl -fsS -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK" + curl -fsS \ + --connect-timeout 5 \ + --max-time 20 \ + --retry 3 \ + --retry-all-errors \ + --retry-delay 2 \ + -H "Content-Type: application/json" \ + -d "$payload" \ + "$DISCORD_WEBHOOK"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/coderabbit-approval-notify.yml at line 40, The curl command used to send the Discord webhook notification lacks timeout and retry mechanisms, making it vulnerable to transient network failures and excessive wait times. Add connection timeout and maximum operation timeout parameters to the curl command (using --connect-timeout and --max-time flags), and include automatic retry logic with delays (using --retry and --retry-delay flags) to make the Discord webhook call more resilient to temporary network issues while ensuring the step completes in a reasonable time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/workflows/coderabbit-approval-notify.yml:
- Line 40: The curl command used to send the Discord webhook notification lacks
timeout and retry mechanisms, making it vulnerable to transient network failures
and excessive wait times. Add connection timeout and maximum operation timeout
parameters to the curl command (using --connect-timeout and --max-time flags),
and include automatic retry logic with delays (using --retry and --retry-delay
flags) to make the Discord webhook call more resilient to temporary network
issues while ensuring the step completes in a reasonable time.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 00853989-478a-4eb6-bcd6-c2cdf9625895
📒 Files selected for processing (1)
.github/workflows/coderabbit-approval-notify.yml
Rename the approval workflow to cover both review automations and add a second job: when zkochan submits an approving review, apply the existing "state: automerge" label. Like the CodeRabbit job, the PR number is passed through the environment rather than interpolated into the run script.
- Scope permissions to each job (top-level permissions: {}) instead of
granting pull-requests: write workflow-wide (zizmor).
- Set allowed_mentions to {parse: []} on the Discord payload so a PR
title containing `@everyone`/`@here` cannot ping the server.
- Add connect/overall timeouts and retries to the Discord curl call.
|
Code review by qodo was updated up to the latest commit 3166ab2 |
| on-maintainer-approval: | ||
| if: >- | ||
| github.event.review.state == 'approved' && | ||
| github.event.review.user.login == 'zkochan' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| pull-requests: write | ||
| env: | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| steps: | ||
| - name: Flag for automerge | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| gh pr edit "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --add-label "state: automerge" |
There was a problem hiding this comment.
1. Stale automerge label 🐞 Bug ≡ Correctness
The workflow adds state: automerge on a single zkochan approval, but never removes it if that approval is later dismissed/changed or becomes stale after new commits. This can leave PRs permanently flagged for automerge, enabling unintended merges if any automation merges based on the label despite the current review state.
Agent Prompt
## Issue description
`state: automerge` is added when `zkochan` submits an approved review, but there is no workflow path to remove that label when the approval is no longer valid (dismissed, changed to changes requested/commented, or made stale by new commits).
## Issue Context
The workflow only listens to `pull_request_review` with `types: [submitted]` and only performs `--add-label` mutations.
## Fix Focus Areas
- .github/workflows/pr-review-automation.yml[5-7]
- .github/workflows/pr-review-automation.yml[54-68]
## Suggested fix
- Add removal logic for `state: automerge`, e.g.:
- Expand `on.pull_request_review.types` to include `dismissed` (and/or handle `submitted` where `review.state != 'approved'`).
- Add a job gated on `github.event.review.user.login == 'zkochan'` that runs `gh pr edit ... --remove-label "state: automerge"` when the review is dismissed or when `review.state` is not `approved`.
- Consider also removing `state: automerge` on `pull_request` `synchronize` (new commits) so the label can’t survive past changes that invalidate prior approvals.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| - name: Announce on Discord | ||
| if: ${{ env.DISCORD_WEBHOOK != '' }} | ||
| run: | | ||
| # allowed_mentions parse:[] stops a PR title like "@everyone" from pinging the Discord server. | ||
| payload="$(jq -n \ | ||
| --arg n "$PR_NUMBER" \ | ||
| --arg t "$PR_TITLE" \ | ||
| --arg u "$PR_URL" \ | ||
| '{content: ("✅ CodeRabbit approved PR #" + $n + ": " + $t + "\n" + $u), allowed_mentions: {parse: []}}')" | ||
| curl -fsS \ | ||
| --connect-timeout 5 \ | ||
| --max-time 20 \ | ||
| --retry 3 \ | ||
| --retry-all-errors \ | ||
| --retry-delay 2 \ | ||
| -H "Content-Type: application/json" \ | ||
| -d "$payload" \ | ||
| "$DISCORD_WEBHOOK" |
There was a problem hiding this comment.
2. Discord step fails job 🐞 Bug ☼ Reliability
If DISCORD_WEBHOOK is set but the webhook is invalid or Discord returns an error, curl -fsS will fail the entire job even after the label is applied. This makes the automation brittle and can produce a red check for a notification-only failure.
Agent Prompt
## Issue description
The Discord notification uses `curl -fsS ...` without `continue-on-error`, so a notification failure marks the whole job as failed even though the label edit already happened.
## Issue Context
This job’s primary purpose is labeling; the Discord step is best-effort.
## Fix Focus Areas
- .github/workflows/pr-review-automation.yml[35-52]
## Suggested fix
- Make the Discord step non-blocking, e.g. add `continue-on-error: true`, or wrap the curl call to avoid failing the step (while still logging the error).
- Optionally emit a clear log line when the webhook call fails so it’s visible in the job output.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
The pr-review-automation workflow merged in #12462 fails at the label step with 'Resource not accessible by integration (addLabelsToLabelable)'. gh pr edit --add-label uses the GraphQL addLabelsToLabelable mutation, which requires issues: write even when labeling a PR; pull-requests: write alone is insufficient. Grant it per job, matching pacquet-integrated-benchmark-comment.yml.
Adds a GitHub Actions workflow (
.github/workflows/pr-review-automation.yml) that reacts to PR review submissions. Two independent jobs on the samepull_request_review(submitted) trigger:1. CodeRabbit approval — when
coderabbitai[bot]submits an approved review:reviewed: coderabbit(already created on this repo; triggers nothing on its own), andDISCORD_WEBHOOKsecret is configured.2. Maintainer approval — when
zkochansubmits an approved review:state: automergelabel.How it works
pull_request_reviewruns in the base-repo context with the repo token and secrets, so it works for fork PRs too.review.state == 'approved'plus the specific reviewer login.permissions:is narrowed topull-requests: write(labels only).Security
PR fields (title, URL, number) are passed to the steps through the environment, never interpolated into a
run:script, so an attacker-controlled PR title can't inject shell commands. The Discord payload is built withjq(proper JSON escaping). No PR code is checked out or executed — important becausepull_request_reviewis a privileged trigger.Heads-up on
state: automergeI couldn't find anything in this repo that consumes
state: automerge(no workflow, no Mergify/Kodiak config). If an external GitHub App reads it, zkochan's approval will trigger a real merge; if nothing reads it, the label is currently inert. Worth confirming the consumer exists.The
zkochangate is hardcoded — if you'd rather key off a maintainers team or CODEOWNERS, that's an easy change.Required to enable the Discord notice (maintainer action)
The Discord step is a no-op until you add the webhook:
DISCORD_WEBHOOK.Until then the labels are applied and the Discord step is skipped cleanly.
Written by an agent (Claude Code, claude-opus-4-8).
Summary by CodeRabbit