mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-05 08:10:14 +00:00
Dry up schemas and ignore vercel PR comments (#206)
This commit is contained in:
parent
014261464f
commit
f5eae4d77b
6 changed files with 142 additions and 97 deletions
|
|
@ -1,36 +1,12 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { createAndEnqueueJob, fetchGitHubAPI } from './utils';
|
||||
|
||||
const githubIssueCommentWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
issue: z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
pull_request: z.object({ url: z.string() }).optional(),
|
||||
}),
|
||||
comment: z.object({
|
||||
id: z.number(),
|
||||
body: z.string(),
|
||||
html_url: z.string(),
|
||||
user: z.object({ login: z.string() }),
|
||||
}),
|
||||
repository: z.object({
|
||||
full_name: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
const githubPullRequestWebhookSchema = z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
head: z.object({ ref: z.string() }),
|
||||
base: z.object({ ref: z.string() }),
|
||||
});
|
||||
import {
|
||||
githubIssueCommentWebhookSchema,
|
||||
githubPullRequestSchema,
|
||||
} from './types';
|
||||
import { createAndEnqueueJob, fetchGitHubAPI, isRoomoteMention } from './utils';
|
||||
|
||||
export async function handleIssueCommentEvent(body: string) {
|
||||
const data = githubIssueCommentWebhookSchema.parse(JSON.parse(body));
|
||||
|
|
@ -40,13 +16,12 @@ export async function handleIssueCommentEvent(body: string) {
|
|||
return NextResponse.json({ message: 'action_ignored' });
|
||||
}
|
||||
|
||||
if (!comment.body.includes('@roomote') || comment.user.login === 'roomote') {
|
||||
if (!isRoomoteMention(comment)) {
|
||||
return NextResponse.json({ message: 'no_roomote_mention' });
|
||||
}
|
||||
|
||||
console.log('🗄️ Issue Comment Webhook ->', data);
|
||||
|
||||
// Handle PR comments (when comment is on a pull request)
|
||||
if (issue.pull_request) {
|
||||
const response = await fetchGitHubAPI(issue.pull_request.url);
|
||||
|
||||
|
|
@ -61,9 +36,7 @@ export async function handleIssueCommentEvent(body: string) {
|
|||
|
||||
// Example:
|
||||
// https://api.github.com/repos/RooCodeInc/Roo-Code/pulls/4796
|
||||
const pull_request = githubPullRequestWebhookSchema.parse(
|
||||
await response.json(),
|
||||
);
|
||||
const pull_request = githubPullRequestSchema.parse(await response.json());
|
||||
|
||||
console.log(`🗄️ Pull Request -> ${issue.pull_request.url}`, pull_request);
|
||||
|
||||
|
|
@ -72,8 +45,8 @@ export async function handleIssueCommentEvent(body: string) {
|
|||
prNumber: pull_request.number,
|
||||
prTitle: pull_request.title,
|
||||
prBody: pull_request.body || '',
|
||||
prBranch: pull_request.head.ref,
|
||||
baseRef: pull_request.base.ref,
|
||||
prBranch: pull_request.head?.ref || '',
|
||||
baseRef: pull_request.base?.ref || '',
|
||||
commentId: comment.id,
|
||||
commentBody: comment.body,
|
||||
commentAuthor: comment.user.login,
|
||||
|
|
@ -93,7 +66,6 @@ export async function handleIssueCommentEvent(body: string) {
|
|||
});
|
||||
}
|
||||
|
||||
// Handle issue comments (when comment is on a regular issue)
|
||||
const type = 'github.issue.comment.respond' as const;
|
||||
|
||||
const payload: JobPayload<typeof type> = {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,10 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { githubIssueWebhookSchema } from './types';
|
||||
import { createAndEnqueueJob } from './utils';
|
||||
|
||||
const githubIssueWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
issue: z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
labels: z.array(z.object({ name: z.string() })),
|
||||
}),
|
||||
repository: z.object({
|
||||
full_name: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
export async function handleIssueEvent(body: string) {
|
||||
const data = githubIssueWebhookSchema.parse(JSON.parse(body));
|
||||
const { action, repository, issue } = data;
|
||||
|
|
@ -33,7 +20,7 @@ export async function handleIssueEvent(body: string) {
|
|||
issue: issue.number,
|
||||
title: issue.title,
|
||||
body: issue.body || '',
|
||||
labels: issue.labels.map(({ name }) => name),
|
||||
labels: issue.labels?.map(({ name }) => name) || [],
|
||||
};
|
||||
|
||||
const { jobId, enqueuedJobId } = await createAndEnqueueJob(
|
||||
|
|
|
|||
|
|
@ -1,23 +1,10 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { db, cloudJobs } from '@roo-code-cloud/db/server';
|
||||
|
||||
import { SlackNotifier } from '@/lib/slack';
|
||||
|
||||
const githubPullRequestWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
pull_request: z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
html_url: z.string(),
|
||||
}),
|
||||
repository: z.object({
|
||||
full_name: z.string(),
|
||||
}),
|
||||
});
|
||||
import { githubPullRequestWebhookSchema } from './types';
|
||||
|
||||
export async function handlePullRequestEvent(body: string) {
|
||||
const data = githubPullRequestWebhookSchema.parse(JSON.parse(body));
|
||||
|
|
@ -50,6 +37,7 @@ export async function handlePullRequestEvent(body: string) {
|
|||
// Filter jobs to find the one matching this repo and issue.
|
||||
const job = jobs.find((j) => {
|
||||
const payload = j.payload as { repo: string; issue: number };
|
||||
|
||||
return (
|
||||
payload.repo === repository.full_name && payload.issue === issueNumber
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,35 +1,9 @@
|
|||
import { NextResponse } from 'next/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { JobPayload } from '@roo-code-cloud/db';
|
||||
|
||||
import { createAndEnqueueJob } from './utils';
|
||||
|
||||
export const githubPullRequestReviewCommentWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
comment: z.object({
|
||||
id: z.number(),
|
||||
body: z.string(),
|
||||
html_url: z.string(),
|
||||
user: z.object({
|
||||
login: z.string(),
|
||||
}),
|
||||
}),
|
||||
pull_request: z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
head: z.object({
|
||||
ref: z.string(),
|
||||
}),
|
||||
base: z.object({
|
||||
ref: z.string(),
|
||||
}),
|
||||
}),
|
||||
repository: z.object({
|
||||
full_name: z.string(),
|
||||
}),
|
||||
});
|
||||
import { githubPullRequestReviewCommentWebhookSchema } from './types';
|
||||
import { createAndEnqueueJob, isRoomoteMention } from './utils';
|
||||
|
||||
export async function handlePullRequestReviewCommentEvent(body: string) {
|
||||
const data = githubPullRequestReviewCommentWebhookSchema.parse(
|
||||
|
|
@ -41,7 +15,7 @@ export async function handlePullRequestReviewCommentEvent(body: string) {
|
|||
return NextResponse.json({ message: 'action_ignored' });
|
||||
}
|
||||
|
||||
if (!comment.body.includes('@roomote') || comment.user.login === 'roomote') {
|
||||
if (!isRoomoteMention(comment)) {
|
||||
return NextResponse.json({ message: 'no_roomote_mention' });
|
||||
}
|
||||
|
||||
|
|
@ -52,8 +26,8 @@ export async function handlePullRequestReviewCommentEvent(body: string) {
|
|||
prNumber: pull_request.number,
|
||||
prTitle: pull_request.title,
|
||||
prBody: pull_request.body || '',
|
||||
prBranch: pull_request.head.ref,
|
||||
baseRef: pull_request.base.ref,
|
||||
prBranch: pull_request.head?.ref || '',
|
||||
baseRef: pull_request.base?.ref || '',
|
||||
commentId: comment.id,
|
||||
commentBody: comment.body,
|
||||
commentAuthor: comment.user.login,
|
||||
|
|
|
|||
119
apps/roomote/src/app/api/webhooks/github/handlers/types.ts
Normal file
119
apps/roomote/src/app/api/webhooks/github/handlers/types.ts
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* GithubComment
|
||||
*/
|
||||
|
||||
export const githubCommentSchema = z.object({
|
||||
id: z.number(),
|
||||
body: z.string(),
|
||||
html_url: z.string(),
|
||||
user: z.object({
|
||||
login: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
export type GithubComment = z.infer<typeof githubCommentSchema>;
|
||||
|
||||
/**
|
||||
* GithubPullRequest
|
||||
*/
|
||||
|
||||
export const githubPullRequestSchema = z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
head: z
|
||||
.object({
|
||||
ref: z.string(),
|
||||
})
|
||||
.optional(),
|
||||
base: z
|
||||
.object({
|
||||
ref: z.string(),
|
||||
})
|
||||
.optional(),
|
||||
html_url: z.string(),
|
||||
});
|
||||
|
||||
export type GithubPullRequest = z.infer<typeof githubPullRequestSchema>;
|
||||
|
||||
/**
|
||||
* GithubIssue
|
||||
*/
|
||||
|
||||
export const githubIssueSchema = z.object({
|
||||
number: z.number(),
|
||||
title: z.string(),
|
||||
body: z.string().nullable(),
|
||||
pull_request: z.object({ url: z.string() }).optional(),
|
||||
labels: z.array(z.object({ name: z.string() })).optional(),
|
||||
});
|
||||
|
||||
export type GithubIssue = z.infer<typeof githubIssueSchema>;
|
||||
|
||||
/**
|
||||
* GithubRepository
|
||||
*/
|
||||
|
||||
export const githubRepositorySchema = z.object({
|
||||
full_name: z.string(),
|
||||
});
|
||||
|
||||
export type GithubRepository = z.infer<typeof githubRepositorySchema>;
|
||||
|
||||
/**
|
||||
* GithubPullRequestReviewCommentWebhook
|
||||
*/
|
||||
|
||||
export const githubPullRequestReviewCommentWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
comment: githubCommentSchema,
|
||||
pull_request: githubPullRequestSchema,
|
||||
repository: githubRepositorySchema,
|
||||
});
|
||||
|
||||
export type GithubPullRequestReviewCommentWebhook = z.infer<
|
||||
typeof githubPullRequestReviewCommentWebhookSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* GithubIssueCommentWebhook
|
||||
*/
|
||||
|
||||
export const githubIssueCommentWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
issue: githubIssueSchema,
|
||||
comment: githubCommentSchema,
|
||||
repository: githubRepositorySchema,
|
||||
});
|
||||
|
||||
export type GithubIssueCommentWebhook = z.infer<
|
||||
typeof githubIssueCommentWebhookSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* GithubPullRequestWebhook
|
||||
*/
|
||||
|
||||
export const githubPullRequestWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
pull_request: githubPullRequestSchema,
|
||||
repository: githubRepositorySchema,
|
||||
});
|
||||
|
||||
export type GithubPullRequestWebhook = z.infer<
|
||||
typeof githubPullRequestWebhookSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* GithubIssueWebhook
|
||||
*/
|
||||
|
||||
export const githubIssueWebhookSchema = z.object({
|
||||
action: z.string(),
|
||||
issue: githubIssueSchema,
|
||||
repository: githubRepositorySchema,
|
||||
});
|
||||
|
||||
export type GithubIssueWebhook = z.infer<typeof githubIssueWebhookSchema>;
|
||||
|
|
@ -8,6 +8,7 @@ import {
|
|||
} from '@roo-code-cloud/db/server';
|
||||
|
||||
import { enqueue } from '@/lib';
|
||||
import type { GithubComment } from './types';
|
||||
|
||||
export function verifySignature(
|
||||
body: string,
|
||||
|
|
@ -57,3 +58,7 @@ export async function fetchGitHubAPI(url: string, options: RequestInit = {}) {
|
|||
|
||||
return fetch(url, { ...options, headers });
|
||||
}
|
||||
|
||||
export const isRoomoteMention = (comment: GithubComment) =>
|
||||
comment.body.includes('@roomote') &&
|
||||
!['roomote', 'vercel'].includes(comment.user.login);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue