Skip to content

Commit fe2414b

Browse files
committed
add button to rerun CRA in checks tab
1 parent aeffbf6 commit fe2414b

File tree

3 files changed

+237
-145
lines changed

3 files changed

+237
-145
lines changed

src/github/client.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ export class GitHubClient {
113113
text?: string;
114114
};
115115
details_url?: string;
116+
actions?: Array<{
117+
label: string;
118+
description: string;
119+
identifier: string;
120+
}>;
116121
}
117122
): Promise<any> {
118123
const url = `${this.baseUrl}/repos/${owner}/${repo}/check-runs`;
@@ -124,6 +129,7 @@ export class GitHubClient {
124129
...(options.conclusion && { conclusion: options.conclusion }),
125130
...(options.output && { output: options.output }),
126131
...(options.details_url && { details_url: options.details_url }),
132+
...(options.actions && { actions: options.actions }),
127133
};
128134

129135
const response = await this.makeRequest(url, {
@@ -152,6 +158,11 @@ export class GitHubClient {
152158
text?: string;
153159
};
154160
details_url?: string;
161+
actions?: Array<{
162+
label: string;
163+
description: string;
164+
identifier: string;
165+
}>;
155166
}
156167
): Promise<any> {
157168
const url = `${this.baseUrl}/repos/${owner}/${repo}/check-runs/${checkRunId}`;

src/github/process-review.ts

Lines changed: 150 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -4,163 +4,168 @@ import { GitHubClient } from "./client.js";
44
import { CHECK_STATUS, CHECK_CONCLUSION, PRDetails, GitHubPullRequestEvent } from "./types.js";
55

66
export async function processReview(
7-
jobId: string,
8-
installationId: number,
9-
payload: GitHubPullRequestEvent
10-
): Promise<void> {
11-
const config = await getConfig();
12-
const githubClient = GitHubClient.forInstallation(config, installationId);
13-
14-
try {
15-
// Extract PR information
16-
const prNumber = payload.pull_request.number;
17-
const repositoryId = payload.repository.id;
18-
const commitSha = payload.pull_request.head.sha;
19-
const owner = payload.repository.owner.login;
20-
const repo = payload.repository.name;
21-
22-
if (!prNumber || !repositoryId || !commitSha) {
23-
const error = 'Missing required PR information';
24-
console.error(error);
25-
throw new Error(error);
26-
}
7+
jobId: string,
8+
installationId: number,
9+
payload: GitHubPullRequestEvent
10+
): Promise<void> {
11+
const config = await getConfig();
12+
const githubClient = GitHubClient.forInstallation(config, installationId);
2713

28-
// Generate PR URL
29-
const prUrl = payload.pull_request.html_url;
14+
try {
15+
// Extract PR information
16+
const prNumber = payload.pull_request.number;
17+
const repositoryId = payload.repository.id;
18+
const commitSha = payload.pull_request.head.sha;
19+
const owner = payload.repository.owner.login;
20+
const repo = payload.repository.name;
3021

31-
// Create check run
32-
const checkRun = await githubClient.createCheckRun(owner, repo, commitSha, {
33-
name: config.github.check_name,
34-
status: CHECK_STATUS.IN_PROGRESS,
35-
output: {
36-
title: 'Code Review',
37-
summary: 'Analyzing changes...',
38-
},
39-
details_url: prUrl,
40-
});
22+
if (!prNumber || !repositoryId || !commitSha) {
23+
const error = 'Missing required PR information';
24+
console.error(error);
25+
throw new Error(error);
26+
}
4127

42-
// Get diff content from GitHub API
43-
console.log('Fetching diff content from GitHub API...');
44-
const diffContent = await githubClient.getPRDiff(owner, repo, prNumber);
45-
46-
if (!diffContent) {
47-
const error = 'No diff content found';
48-
console.error(error);
49-
throw new Error(error);
50-
}
28+
// Generate PR URL
29+
const prUrl = payload.pull_request.html_url;
30+
31+
// Create check run
32+
const checkRun = await githubClient.createCheckRun(owner, repo, commitSha, {
33+
name: config.github.check_name,
34+
status: CHECK_STATUS.IN_PROGRESS,
35+
output: {
36+
title: 'Code Review',
37+
summary: 'Analyzing changes...',
38+
},
39+
details_url: prUrl,
40+
});
41+
42+
// Get diff content from GitHub API
43+
console.log('Fetching diff content from GitHub API...');
44+
const diffContent = await githubClient.getPRDiff(owner, repo, prNumber);
45+
46+
if (!diffContent) {
47+
const error = 'No diff content found';
48+
console.error(error);
49+
throw new Error(error);
50+
}
51+
52+
console.log(`Retrieved diff content (${diffContent.length} chars)`);
53+
54+
// Create PR details object
55+
const prDetails: PRDetails = {
56+
pr_number: prNumber,
57+
repository_id: repositoryId,
58+
commit_sha: commitSha,
59+
pr_url: prUrl,
60+
};
61+
62+
const prDetailsContent = `Repository: ${payload.repository.full_name}, PR Number: ${prDetails.pr_number}, Commit SHA: ${prDetails.commit_sha}, PR URL: ${prDetails.pr_url}`;
63+
64+
console.log(`Calling reviewDiff() for job ${jobId}`);
65+
const reviewResult = await reviewDiff(diffContent, prDetailsContent, installationId);
66+
console.log(`Review completed for job ${jobId}`);
67+
68+
// Read collected comments from file
69+
const fs = await import('fs');
70+
const commentsFilePath = reviewResult.commentsFilePath;
71+
72+
if (fs.existsSync(commentsFilePath)) {
73+
try {
74+
console.log(`📖 Reading collected comments from ${commentsFilePath}`);
75+
const fileContent = fs.readFileSync(commentsFilePath, 'utf8').trim();
76+
77+
if (fileContent) {
78+
const commentLines = fileContent.split('\n');
79+
const comments = commentLines.map(line => JSON.parse(line));
80+
81+
const inlineComments = comments.filter(c => c.type === 'inline');
82+
const generalComments = comments.filter(c => c.type === 'general');
5183

52-
console.log(`Retrieved diff content (${diffContent.length} chars)`);
53-
54-
// Create PR details object
55-
const prDetails: PRDetails = {
56-
pr_number: prNumber,
57-
repository_id: repositoryId,
58-
commit_sha: commitSha,
59-
pr_url: prUrl,
60-
};
61-
62-
const prDetailsContent = `Repository: ${payload.repository.full_name}, PR Number: ${prDetails.pr_number}, Commit SHA: ${prDetails.commit_sha}, PR URL: ${prDetails.pr_url}`;
63-
64-
console.log(`Calling reviewDiff() for job ${jobId}`);
65-
const reviewResult = await reviewDiff(diffContent, prDetailsContent, installationId);
66-
console.log(`Review completed for job ${jobId}`);
67-
68-
// Read collected comments from file
69-
const fs = await import('fs');
70-
const commentsFilePath = reviewResult.commentsFilePath;
71-
72-
if (fs.existsSync(commentsFilePath)) {
73-
try {
74-
console.log(`📖 Reading collected comments from ${commentsFilePath}`);
75-
const fileContent = fs.readFileSync(commentsFilePath, 'utf8').trim();
76-
77-
if (fileContent) {
78-
const commentLines = fileContent.split('\n');
79-
const comments = commentLines.map(line => JSON.parse(line));
80-
81-
const inlineComments = comments.filter(c => c.type === 'inline');
82-
const generalComments = comments.filter(c => c.type === 'general');
83-
84-
console.log(`📝 Collected ${inlineComments.length} inline comments and ${generalComments.length} general comments`);
85-
86-
// Create review summary from general comments
87-
const reviewSummary = generalComments.length > 0
88-
? generalComments.map(c => c.message).join('\n\n')
89-
: 'Code review completed.';
90-
91-
// Post aggregated review
92-
console.log('📋 Posting aggregated PR review...');
93-
await githubClient.createPRReview(
94-
owner,
95-
repo,
96-
prNumber,
97-
reviewSummary,
98-
'COMMENT',
99-
inlineComments.map(comment => ({
100-
path: comment.path,
101-
line: comment.line,
102-
body: comment.message
103-
}))
104-
);
105-
console.log('✅ PR review posted successfully');
106-
} else {
107-
console.log('📝 No comments collected, skipping review creation');
108-
}
109-
110-
// Clean up the comments file
111-
fs.unlinkSync(commentsFilePath);
112-
console.log('🗑️ Cleaned up comments file');
113-
114-
} catch (error) {
115-
console.error('❌ Failed to read or process comments file:', error);
84+
console.log(`📝 Collected ${inlineComments.length} inline comments and ${generalComments.length} general comments`);
85+
86+
// Create review summary from general comments
87+
const reviewSummary = generalComments.length > 0
88+
? generalComments.map(c => c.message).join('\n\n')
89+
: 'Code review completed.';
90+
91+
// Post aggregated review
92+
console.log('📋 Posting aggregated PR review...');
93+
await githubClient.createPRReview(
94+
owner,
95+
repo,
96+
prNumber,
97+
reviewSummary,
98+
'COMMENT',
99+
inlineComments.map(comment => ({
100+
path: comment.path,
101+
line: comment.line,
102+
body: comment.message
103+
}))
104+
);
105+
console.log('✅ PR review posted successfully');
106+
} else {
107+
console.log('📝 No comments collected, skipping review creation');
116108
}
117-
} else {
118-
console.log('📝 No comments file found, skipping review creation');
109+
110+
// Clean up the comments file
111+
fs.unlinkSync(commentsFilePath);
112+
console.log('🗑️ Cleaned up comments file');
113+
114+
} catch (error) {
115+
console.error('❌ Failed to read or process comments file:', error);
119116
}
117+
} else {
118+
console.log('📝 No comments file found, skipping review creation');
119+
}
120120

121-
// Update check run with success (simplified since review details are now in PR review)
122-
await githubClient.updateCheckRun(owner, repo, checkRun.id, {
123-
status: CHECK_STATUS.COMPLETED,
124-
conclusion: CHECK_CONCLUSION.SUCCESS,
125-
output: {
126-
title: 'Code Review Completed',
127-
summary: 'Code review has been completed successfully. See PR conversation for details.',
128-
},
129-
details_url: prUrl,
130-
});
121+
// Update check run with success (simplified since review details are now in PR review)
122+
await githubClient.updateCheckRun(owner, repo, checkRun.id, {
123+
status: CHECK_STATUS.COMPLETED,
124+
conclusion: CHECK_CONCLUSION.SUCCESS,
125+
output: {
126+
title: 'Code Review Completed',
127+
summary: 'Code review has been completed successfully. See PR conversation for details.',
128+
},
129+
details_url: prUrl,
130+
actions: [{
131+
label: 'Re-run review',
132+
description: 'Request a new code review for this PR',
133+
identifier: 're-run-review'
134+
}]
135+
});
136+
137+
} catch (error) {
138+
console.error(`Review job ${jobId} failed with exception:`, error);
131139

132-
} catch (error) {
133-
console.error(`Review job ${jobId} failed with exception:`, error);
134-
135-
// Post FAILED check run for exceptions
136-
await postFailureCheckRun(githubClient, payload, error instanceof Error ? error.message : String(error));
140+
// Post FAILED check run for exceptions
141+
await postFailureCheckRun(githubClient, payload, error instanceof Error ? error.message : String(error));
137142
}
138143
}
139144

140145
async function postFailureCheckRun(
141146
githubClient: GitHubClient,
142-
payload: GitHubPullRequestEvent,
143-
errorMessage: string
144-
): Promise<void> {
145-
const config = getConfig();
146-
147-
try {
148-
const commitSha = payload.pull_request.head.sha;
149-
const owner = payload.repository.owner.login;
150-
const repo = payload.repository.name;
151-
152-
if (commitSha && owner && repo) {
153-
await githubClient.createCheckRun(owner, repo, commitSha, {
154-
name: config.github.check_name,
155-
status: CHECK_STATUS.COMPLETED,
156-
conclusion: CHECK_CONCLUSION.FAILURE,
157-
output: {
158-
title: 'Code Review Failed',
159-
summary: `Review failed: ${errorMessage.substring(0, 100)}...`,
160-
},
161-
});
162-
}
163-
} catch (error) {
164-
console.error(`Failed to post failure check run:`, error);
147+
payload: GitHubPullRequestEvent,
148+
errorMessage: string
149+
): Promise<void> {
150+
const config = getConfig();
151+
152+
try {
153+
const commitSha = payload.pull_request.head.sha;
154+
const owner = payload.repository.owner.login;
155+
const repo = payload.repository.name;
156+
157+
if (commitSha && owner && repo) {
158+
await githubClient.createCheckRun(owner, repo, commitSha, {
159+
name: config.github.check_name,
160+
status: CHECK_STATUS.COMPLETED,
161+
conclusion: CHECK_CONCLUSION.FAILURE,
162+
output: {
163+
title: 'Code Review Failed',
164+
summary: `Review failed: ${errorMessage.substring(0, 100)}...`,
165+
},
166+
});
165167
}
168+
} catch (error) {
169+
console.error(`Failed to post failure check run:`, error);
170+
}
166171
}

0 commit comments

Comments
 (0)