fix: gate Forgejo review/comment triggers on @claude mention
Previously, all pull_request_comment events on Forgejo triggered the full Claude pipeline unconditionally — both in the workflow if-condition and in trigger.ts. This wasted CI resources and API credits on reviews without @claude mentions (e.g. plain "LGTM" reviews). Workflow: add @claude check via contains() on comment.body and review.body. Trigger validation: replace blind auto-trigger with payload-aware check that inspects available body fields, falling back only when no body exists. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
d9c22ffe50
commit
71fb686885
2 files changed
+24
-18
No files matched your search
@@ -24,7 +24,8 @@ jobs:
|
|||||||
# despite action being 'labeled'). Let all through; trigger.ts validates.
|
# despite action being 'labeled'). Let all through; trigger.ts validates.
|
||||||
if: >-
|
if: >-
|
||||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
||||||
(github.event_name == 'pull_request_review_comment' || github.event_name == 'pull_request_comment') ||
|
(github.event_name == 'pull_request_review_comment' || github.event_name == 'pull_request_comment') &&
|
||||||
|
(contains(github.event.comment.body, '@claude') || contains(github.event.review.body, '@claude')) ||
|
||||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
||||||
(github.event_name == 'issues')
|
(github.event_name == 'issues')
|
||||||
runs-on: grunt
|
runs-on: grunt
|
||||||
|
|||||||
@@ -123,32 +123,37 @@ export function checkContainsTrigger(context: ParsedGitHubContext): boolean {
|
|||||||
isIssueCommentEvent(context) ||
|
isIssueCommentEvent(context) ||
|
||||||
isPullRequestReviewCommentEvent(context)
|
isPullRequestReviewCommentEvent(context)
|
||||||
) {
|
) {
|
||||||
// Forgejo's pull_request_review_comment payload does NOT include a
|
// Forgejo sends both review comments and full reviews as
|
||||||
// top-level `comment` object (it's undefined). On Forgejo, the
|
// `pull_request_comment`, which normalizes to `pull_request_review_comment`.
|
||||||
// workflow `if:` already gates on event name alone, so always trigger
|
// The payload may have `comment.body`, `review.body`, both, or neither.
|
||||||
// here — the actual comment data is fetched via REST in the data
|
// Try all available body fields before giving up.
|
||||||
// fetcher, and non-matching comments won't produce useful output.
|
const payload = context.payload as Record<string, any>;
|
||||||
if (
|
|
||||||
isPullRequestReviewCommentEvent(context) &&
|
|
||||||
detectPlatform() === "forgejo"
|
|
||||||
) {
|
|
||||||
console.log(
|
|
||||||
"Forgejo pull_request_review_comment: triggering (payload lacks comment body)",
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const commentBody = isIssueCommentEvent(context)
|
const commentBody = isIssueCommentEvent(context)
|
||||||
? context.payload.comment.body
|
? context.payload.comment.body
|
||||||
: context.payload.comment.body;
|
: (payload.comment?.body ?? payload.review?.body ?? "");
|
||||||
|
|
||||||
// Check for exact match with word boundaries or punctuation
|
// Check for exact match with word boundaries or punctuation
|
||||||
const regex = new RegExp(
|
const regex = new RegExp(
|
||||||
`(^|\\s)${escapeRegExp(triggerPhrase)}([\\s.,!?;:]|$)`,
|
`(^|\\s)${escapeRegExp(triggerPhrase)}([\\s.,!?;:]|$)`,
|
||||||
);
|
);
|
||||||
if (regex.test(commentBody)) {
|
if (commentBody && regex.test(commentBody)) {
|
||||||
console.log(`Comment contains exact trigger phrase '${triggerPhrase}'`);
|
console.log(`Comment contains exact trigger phrase '${triggerPhrase}'`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On Forgejo, if no body was found in the payload at all, still trigger —
|
||||||
|
// the actual comment data will be fetched via REST in the data fetcher.
|
||||||
|
// This handles edge cases where Forgejo strips body from the webhook payload.
|
||||||
|
if (
|
||||||
|
isPullRequestReviewCommentEvent(context) &&
|
||||||
|
detectPlatform() === "forgejo" &&
|
||||||
|
!commentBody
|
||||||
|
) {
|
||||||
|
console.log(
|
||||||
|
"Forgejo pull_request_review_comment: no body in payload, triggering (data fetched via REST)",
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`No trigger was met for ${triggerPhrase}`);
|
console.log(`No trigger was met for ${triggerPhrase}`);
|
||||||
|
|||||||
Reference in new issue
Block a user