From 84db121a4c4e740fbbfe9cea57496accc25c41f0 Mon Sep 17 00:00:00 2001 From: Daan Schouteden Date: Wed, 3 Jun 2026 10:59:22 +0200 Subject: [PATCH] Accept review_requested on pull_request webhook events. Gitea sends review requests as pull_request/review_requested, not only pull_request_review_request. Co-authored-by: Cursor --- README.md | 2 +- docs/operations.md | 2 +- src/webhook/event-router.ts | 17 +++++++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 901ffb7..7216cc2 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This bot is designed to run once for many repositories in `Bram/*` instead of du - Listens to Gitea webhook events. - Triggers on: - `pull_request` with action `opened` - - `pull_request_review_request` with action `review_requested` when requested reviewer is the bot user + - `pull_request` or `pull_request_review_request` with action `review_requested` when requested reviewer is the bot user - Loads PR metadata and changed files from Gitea. - Builds a review prompt (including optional repo-specific rule files). - Calls Cursor Cloud Agent (`Agent.prompt`) for structured review output. diff --git a/docs/operations.md b/docs/operations.md index 15d2c7a..974e201 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -4,7 +4,7 @@ - Processes only: - `pull_request` with action `opened` - - `pull_request_review_request` with action `review_requested` and reviewer matching bot login + - `pull_request` or `pull_request_review_request` with action `review_requested` and reviewer matching bot login - Idempotency key: `{owner}/{repo}#{pr_number}#{head_sha}` - Removes bot from reviewers after a successful review post diff --git a/src/webhook/event-router.ts b/src/webhook/event-router.ts index 69bf1a0..e251f75 100644 --- a/src/webhook/event-router.ts +++ b/src/webhook/event-router.ts @@ -1,5 +1,7 @@ import { RoutedEvent, PullRequestWebhookPayload } from "../types/events.js"; +const REVIEW_REQUEST_EVENTS = new Set(["pull_request", "pull_request_review_request"]); + export function routeEvent(input: { eventName: string | undefined; payload: PullRequestWebhookPayload; @@ -12,12 +14,23 @@ export function routeEvent(input: { } if ( - eventName === "pull_request_review_request" && + eventName && + REVIEW_REQUEST_EVENTS.has(eventName) && payload.action === "review_requested" && - payload.requested_reviewer?.login === botLogin + isReviewRequestedForBot(payload, botLogin) ) { return { kind: "review_requested", payload }; } return null; } + +function isReviewRequestedForBot(payload: PullRequestWebhookPayload, botLogin: string): boolean { + if (payload.requested_reviewer?.login === botLogin) { + return true; + } + + return (payload.pull_request.requested_reviewers ?? []).some( + (reviewer) => reviewer.login === botLogin + ); +}