Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions apps/api/src/handlers/github/notifyPrReviewActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export function buildPrReviewActivityNotificationInput(
event: {
kind: 'review',
authorLogin,
...(review.commit_id ? { reviewHeadSha: review.commit_id } : {}),
reviewState: review.state,
...(review.html_url ? { url: review.html_url } : {}),
...(GitHubSchemas.isRoomoteGitHubLogin(authorLogin)
Expand Down Expand Up @@ -110,6 +111,7 @@ export function buildPrReviewActivityNotificationInput(
event: {
kind: 'review_comment',
authorLogin,
...(comment.commit_id ? { reviewHeadSha: comment.commit_id } : {}),
...(comment.html_url ? { url: comment.html_url } : {}),
...(GitHubSchemas.isRoomoteGitHubLogin(authorLogin)
? { roomoteAuthored: true }
Expand Down Expand Up @@ -254,6 +256,7 @@ export function buildPrReviewSummaryNotification(
event: {
kind: 'review_summary',
authorLogin,
...(markerSha ? { reviewHeadSha: markerSha } : {}),
summary,
...(comment.html_url ? { url: comment.html_url } : {}),
roomoteAuthored: true,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import {
REVIEW_STATUS_START_MARKER,
REVIEW_SUMMARY_MARKER,
getMarkedSection,
isReviewInProgressStatusLine,
} from '@roomote/cloud-agents/server';
import {
generateTrackedNonTaskObject,
NON_TASK_INFERENCE_SURFACES,
} from '@roomote/cloud-agents/server/non-task-provider-usage';
import type { TaskRun } from '@roomote/db/server';
import { createTaskRunGitHubToken, getOctokit } from '@roomote/github';
import {
Schemas as GitHubSchemas,
createTaskRunGitHubToken,
getOctokit,
} from '@roomote/github';
import { setLatestSlackBotReply, trackSlackBotReply } from '@roomote/slack';
import {
ACP_ENVELOPE_EVENT_TYPES,
Expand Down Expand Up @@ -65,6 +70,7 @@ export type PrReviewTriageContext = {
unresolvedThreadCount: number | null;
latestReviewStatus: string | null;
latestReviewSummaryComment: string | null;
latestTerminalReviewSummaryHeadSha: string | null;
/**
* Per-check CI state for the PR head, when available. Fed into the
* triage LLM so the chat message can mention CI naturally.
Expand Down Expand Up @@ -527,6 +533,12 @@ function sanitizeReviewStatus(status: string): string {
.slice(0, MAX_REVIEW_STATUS_LENGTH);
}

function getReviewSummaryHeadSha(body: string): string | null {
return (
body.match(/<!--\s*roomote-review-summary\s+sha=([0-9a-f]+)/i)?.[1] ?? null
);
}

async function fetchPrDiscussionSignals({
taskRun,
repository,
Expand All @@ -551,14 +563,20 @@ async function fetchPrDiscussionSignals({
unresolvedThreadCount: null,
latestReviewStatus: null,
latestReviewSummaryComment: null,
latestTerminalReviewSummaryHeadSha: null,
};
}

let latestReviewStatus: string | null = null;
let latestReviewSummaryComment: string | null = null;
let latestTerminalReviewSummaryHeadSha: string | null = null;

for (const comment of result.issueComments) {
if (!comment.body.trimStart().startsWith(REVIEW_SUMMARY_MARKER)) {
if (
!comment.author ||
!GitHubSchemas.isRoomoteGitHubLogin(comment.author) ||
Comment thread
roomote-roomote[bot] marked this conversation as resolved.
Outdated
!comment.body.trimStart().startsWith(REVIEW_SUMMARY_MARKER)
) {
continue;
}

Expand All @@ -570,6 +588,11 @@ async function fetchPrDiscussionSignals({

if (status?.trim()) {
latestReviewStatus = sanitizeReviewStatus(status);
latestTerminalReviewSummaryHeadSha = isReviewInProgressStatusLine(
status.trim().split('\n')[0] ?? '',
)
? null
: getReviewSummaryHeadSha(comment.body);
}

latestReviewSummaryComment = comment.body.trim();
Expand All @@ -584,6 +607,7 @@ async function fetchPrDiscussionSignals({
).length,
latestReviewStatus,
latestReviewSummaryComment,
latestTerminalReviewSummaryHeadSha,
};
}

Expand Down Expand Up @@ -618,6 +642,7 @@ export async function gatherPrReviewTriageContext({
unresolvedThreadCount: null,
latestReviewStatus: null,
latestReviewSummaryComment: null,
latestTerminalReviewSummaryHeadSha: null,
};
}
})(),
Expand Down Expand Up @@ -792,12 +817,25 @@ export async function preparePrReviewNotificationDelivery({
prNumber: request.prNumber,
sourceControlProvider: request.sourceControlProvider,
});
const eventsToTriage = context.latestTerminalReviewSummaryHeadSha
? events.filter(
(event) =>
event.kind === 'review_summary' ||
!event.roomoteAuthored ||
event.reviewHeadSha !== context.latestTerminalReviewSummaryHeadSha,
)
: events;

if (eventsToTriage.length === 0) {
return { post: false, reason: 'not_worth_notifying' };
}

const triage = await triagePrReviewActivity({
taskId: request.taskId,
repository: request.repository,
prNumber: request.prNumber,
prUrl: request.prUrl,
events,
events: eventsToTriage,
context,
sourceControlProvider: request.sourceControlProvider,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const SCHEDULED_MARKER_TTL_BUFFER_SECONDS = 15 * 60;
export const prReviewActivityEventSchema = z.object({
kind: z.enum(['review', 'review_comment', 'review_summary']),
authorLogin: z.string(),
/** Commit SHA reviewed by this event, used to coalesce one review pass. */
reviewHeadSha: z.string().optional(),
/** GitHub review state for `review` events, e.g. `approved`. */
reviewState: z.string().optional(),
/** Short human-readable summary text for `review_summary` events. */
Expand Down
Loading