Skip to content

Commit d7a41f3

Browse files
committed
refactor: reduce time taken to post review-in-progress comment
1 parent 2fbbf5d commit d7a41f3

File tree

3 files changed

+53
-61
lines changed

3 files changed

+53
-61
lines changed

api/models/ai-review.model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ export interface PullRequestData {
1919
formattedPullRequest: string;
2020
/** Raw concatenated git diff from the *previous* review cycle, used for follow-up prompts. */
2121
previousDiff?: string;
22+
/** ID of the in-progress comment already posted before queueing the job */
23+
pendingCommentId?: string;
2224
}
2325

2426
export interface ChangedFile {

api/services/pr-review/orchestration.service.ts

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class AIReviewOrchestrationService {
3333
prNumber: prData.prNumber,
3434
prUrl: prData.prUrl,
3535
repositoryName: prData.repositoryName,
36+
commentId: prData.pendingCommentId,
3637
mergeScore: 0,
3738
rulesViolated: [],
3839
rulesPassed: [],
@@ -192,25 +193,6 @@ export class AIReviewOrchestrationService {
192193
// Create initial review result record
193194
const initialResult = await this.createInitialReviewResult(prData);
194195

195-
// Post an "in progress" comment so contributors know a review is underway
196-
try {
197-
const commentResult = await AIReviewCommentService.postInProgressComment(
198-
prData.installationId,
199-
prData.repositoryName,
200-
prData.prNumber
201-
);
202-
203-
if (commentResult.success && commentResult.commentId) {
204-
await prisma.aIReviewResult.update({
205-
where: { id: initialResult.id },
206-
data: { commentId: commentResult.commentId }
207-
});
208-
}
209-
} catch (inProgressError) {
210-
// Non-fatal — log and continue with analysis
211-
dataLogger.error("Failed to post in-progress comment", { inProgressError });
212-
}
213-
214196
// Execute analysis
215197
const reviewResult = await PRAnalysisService.analyzePullRequest(prData);
216198

@@ -291,24 +273,6 @@ export class AIReviewOrchestrationService {
291273
const initialResult = await this.createInitialReviewResult(prData);
292274
recordId = initialResult.id;
293275

294-
// Post a "follow-up review in progress" notification comment
295-
try {
296-
const commentResult = await AIReviewCommentService.postFollowUpInProgressComment(
297-
prData.installationId,
298-
prData.repositoryName,
299-
prData.prNumber
300-
);
301-
302-
if (commentResult.success && commentResult.commentId) {
303-
await prisma.aIReviewResult.update({
304-
where: { id: recordId },
305-
data: { commentId: commentResult.commentId }
306-
});
307-
}
308-
} catch (inProgressError) {
309-
dataLogger.error("Failed to post follow-up in-progress comment", { inProgressError });
310-
}
311-
312276
// Run the follow-up analysis
313277
const reviewResult = await PRAnalysisService.analyzePullRequestFollowUp(prData);
314278

api/services/pr-review/workflow-integration.service.ts

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { PullRequestData, GitHubWebhookPayload } from "../../models/ai-review.model";
22
import { backgroundJobService, BackgroundJobService } from "../background-job.service";
33
import { AIReviewOrchestrationService } from "./orchestration.service";
4+
import { AIReviewCommentService } from "./comment.service";
45
import { PRAnalysisService } from "./pr-analysis.service";
56
import { PRAnalysisError } from "../../models/error.model";
67
import { dataLogger, messageLogger } from "../../config/logger.config";
@@ -75,6 +76,7 @@ export class WorkflowIntegrationService {
7576
reason?: string;
7677
}> {
7778
const startTime = Date.now();
79+
let prData: PullRequestData = {} as PullRequestData;
7880

7981
try {
8082
dataLogger.info(
@@ -86,10 +88,47 @@ export class WorkflowIntegrationService {
8688
}
8789
);
8890

91+
// Determine whether this is a follow-up (synchronize) or initial review.
92+
// Manual triggers ("review" comment) always queue as an initial review.
93+
const isFollowUp = !payload.manualTrigger && payload.action === "synchronize";
94+
const { pull_request, repository, installation } = payload;
95+
96+
let isActualFollowUp = false;
97+
if (isFollowUp) {
98+
// Check whether a completed initial review already exists for this PR
99+
isActualFollowUp = await this.orchestrationService.hasCompletedReview(
100+
installation.id.toString(),
101+
pull_request.number,
102+
repository.full_name
103+
);
104+
}
105+
106+
// Post an "in progress" comment so contributors know a review is underway
107+
try {
108+
const commentResult = isActualFollowUp
109+
? await AIReviewCommentService.postFollowUpInProgressComment(
110+
installation.id.toString(),
111+
repository.full_name,
112+
pull_request.number
113+
)
114+
: await AIReviewCommentService.postInProgressComment(
115+
installation.id.toString(),
116+
repository.full_name,
117+
pull_request.number
118+
);
119+
120+
if (commentResult.success && commentResult.commentId) {
121+
prData.pendingCommentId = commentResult.commentId;
122+
}
123+
} catch (inProgressError) {
124+
dataLogger.error("Failed to post in-progress comment", { inProgressError });
125+
}
126+
89127
// Extract and validate PR data
90-
let prData: PullRequestData;
91128
try {
129+
const pendingCommentId = prData.pendingCommentId;
92130
prData = await PRAnalysisService.createCompletePRData(payload);
131+
prData.pendingCommentId = pendingCommentId;
93132
} catch (error) {
94133
if (error instanceof PRAnalysisError && error.code === "PR_NOT_ELIGIBLE_ERROR") {
95134
dataLogger.info(
@@ -105,32 +144,19 @@ export class WorkflowIntegrationService {
105144
// Log analysis decision
106145
PRAnalysisService.logAnalysisDecision(prData, true);
107146

108-
// Determine whether this is a follow-up (synchronize) or initial review.
109-
// Manual triggers ("review" comment) always queue as an initial review.
110-
const isFollowUp = !payload.manualTrigger && payload.action === "synchronize";
111-
112147
let jobId: string;
113-
if (isFollowUp) {
114-
// Check whether a completed initial review already exists for this PR
115-
const hasPreviousReview = await this.orchestrationService.hasCompletedReview(
116-
prData.installationId,
117-
prData.prNumber,
118-
prData.repositoryName
119-
);
120-
121-
if (hasPreviousReview) {
122-
// Queue as a follow-up job
123-
jobId = await this.jobQueue.addPRAnalysisJob(prData, true);
124-
dataLogger.info("Queued follow-up review job", { jobId, prNumber: prData.prNumber });
125-
} else {
126-
// No prior review exists yet — treat this like an initial review
127-
jobId = await this.jobQueue.addPRAnalysisJob(prData, false);
128-
dataLogger.info("No prior review found; queued as initial review", { jobId, prNumber: prData.prNumber });
129-
}
148+
if (isActualFollowUp) {
149+
// Queue as a follow-up job
150+
jobId = await this.jobQueue.addPRAnalysisJob(prData, true);
151+
dataLogger.info("Queued follow-up review job", { jobId, prNumber: prData.prNumber });
130152
} else {
131-
// Initial review (opened / ready_for_review)
153+
// No prior review exists yet, or it's an opened/ready_for_review event — treat this like an initial review
132154
jobId = await this.jobQueue.addPRAnalysisJob(prData, false);
133-
dataLogger.info("Queued initial review job", { jobId, prNumber: prData.prNumber });
155+
if (isFollowUp) {
156+
dataLogger.info("No prior review found; queued as initial review", { jobId, prNumber: prData.prNumber });
157+
} else {
158+
dataLogger.info("Queued initial review job", { jobId, prNumber: prData.prNumber });
159+
}
134160
}
135161

136162
dataLogger.info(

0 commit comments

Comments
 (0)