Skip to content

Commit f19d73f

Browse files
authored
Merge pull request #181 from anc95/chao
feat: add lgtm
2 parents b03bb41 + 5743464 commit f19d73f

File tree

4 files changed

+79
-27
lines changed

4 files changed

+79
-27
lines changed

action/index.cjs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150469,18 +150469,20 @@ const robot = (app) => {
150469150469
const includePatterns = (process.env.INCLUDE_PATTERNS || '').split(',').filter((v) => Boolean(v.trim()));
150470150470
loglevel_1.default.debug('ignoreList:', ignoreList);
150471150471
loglevel_1.default.debug('ignorePatterns:', ignorePatterns);
150472+
loglevel_1.default.debug('includePatterns:', includePatterns);
150472150473
changedFiles = changedFiles?.filter((file) => {
150473150474
const url = new URL(file.contents_url);
150475+
const pathname = decodeURIComponent(url.pathname);
150474150476
// if includePatterns is not empty, only include files that match the pattern
150475150477
if (includePatterns.length) {
150476-
return matchPatterns(includePatterns, url.pathname);
150478+
return matchPatterns(includePatterns, pathname);
150477150479
}
150478150480
if (ignoreList.includes(file.filename)) {
150479150481
return false;
150480150482
}
150481150483
// if ignorePatterns is not empty, ignore files that match the pattern
150482150484
if (ignorePatterns.length) {
150483-
return !matchPatterns(ignorePatterns, url.pathname);
150485+
return !matchPatterns(ignorePatterns, pathname);
150484150486
}
150485150487
return true;
150486150488
});
@@ -150502,10 +150504,10 @@ const robot = (app) => {
150502150504
}
150503150505
try {
150504150506
const res = await chat?.codeReview(patch);
150505-
if (!!res) {
150507+
if (!res.lgtm && !!res.review_comment) {
150506150508
ress.push({
150507150509
path: file.filename,
150508-
body: res,
150510+
body: res.review_comment,
150509150511
position: patch.split('\n').length - 1,
150510150512
});
150511150513
}
@@ -150519,7 +150521,7 @@ const robot = (app) => {
150519150521
repo: repo.repo,
150520150522
owner: repo.owner,
150521150523
pull_number: context.pullRequest().pull_number,
150522-
body: "Code review by ChatGPT",
150524+
body: ress.length ? "Code review by ChatGPT" : "LGTM 👍",
150523150525
event: 'COMMENT',
150524150526
commit_id: commits[commits.length - 1].sha,
150525150527
comments: ress,
@@ -150588,15 +150590,23 @@ class Chat {
150588150590
const answerLanguage = process.env.LANGUAGE
150589150591
? `Answer me in ${process.env.LANGUAGE},`
150590150592
: '';
150591-
const prompt = process.env.PROMPT ||
150592-
'Below is a code patch, please help me do a brief code review on it. Any bug risks and/or improvement suggestions are welcome:';
150593-
return `${prompt}, ${answerLanguage}:
150594-
${patch}
150593+
const userPrompt = process.env.PROMPT || 'Please review the following code patch. Focus on potential bugs, risks, and improvement suggestions.';
150594+
const jsonFormatRequirement = '\nProvide your feedback in a strict JSON format with the following structure:\n' +
150595+
'{\n' +
150596+
' "lgtm": boolean, // true if the code looks good to merge, false if there are concerns\n' +
150597+
' "review_comment": string // Your detailed review comments. You can use markdown syntax in this string, but the overall response must be a valid JSON\n' +
150598+
'}\n' +
150599+
'Ensure your response is a valid JSON object.\n';
150600+
return `${userPrompt}${jsonFormatRequirement} ${answerLanguage}:
150601+
${patch}
150595150602
`;
150596150603
};
150597150604
codeReview = async (patch) => {
150598150605
if (!patch) {
150599-
return '';
150606+
return {
150607+
lgtm: true,
150608+
review_comment: ""
150609+
};
150600150610
}
150601150611
console.time('code-review cost');
150602150612
const prompt = this.generatePrompt(patch);
@@ -150611,12 +150621,27 @@ class Chat {
150611150621
temperature: +(process.env.temperature || 0) || 1,
150612150622
top_p: +(process.env.top_p || 0) || 1,
150613150623
max_tokens: process.env.max_tokens ? +process.env.max_tokens : undefined,
150624+
response_format: {
150625+
type: "json_object"
150626+
},
150614150627
});
150615150628
console.timeEnd('code-review cost');
150616150629
if (res.choices.length) {
150617-
return res.choices[0].message.content;
150630+
try {
150631+
const json = JSON.parse(res.choices[0].message.content || "");
150632+
return json;
150633+
}
150634+
catch (e) {
150635+
return {
150636+
lgtm: false,
150637+
review_comment: res.choices[0].message.content || ""
150638+
};
150639+
}
150618150640
}
150619-
return '';
150641+
return {
150642+
lgtm: true,
150643+
review_comment: ""
150644+
};
150620150645
};
150621150646
}
150622150647
exports.Chat = Chat;

action/src/chat.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@ export declare class Chat {
33
private isAzure;
44
constructor(apikey: string);
55
private generatePrompt;
6-
codeReview: (patch: string) => Promise<string | null>;
6+
codeReview: (patch: string) => Promise<{
7+
lgtm: boolean;
8+
review_comment: string;
9+
}>;
710
}

src/bot.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,15 @@ export const robot = (app: Probot) => {
110110

111111
log.debug('ignoreList:', ignoreList);
112112
log.debug('ignorePatterns:', ignorePatterns);
113+
log.debug('includePatterns:', includePatterns);
113114

114115
changedFiles = changedFiles?.filter(
115116
(file) => {
116117
const url = new URL(file.contents_url)
118+
const pathname = decodeURIComponent(url.pathname)
117119
// if includePatterns is not empty, only include files that match the pattern
118120
if (includePatterns.length) {
119-
return matchPatterns(includePatterns, url.pathname)
121+
return matchPatterns(includePatterns, pathname)
120122
}
121123

122124
if (ignoreList.includes(file.filename)) {
@@ -125,7 +127,7 @@ export const robot = (app: Probot) => {
125127

126128
// if ignorePatterns is not empty, ignore files that match the pattern
127129
if (ignorePatterns.length) {
128-
return !matchPatterns(ignorePatterns, url.pathname)
130+
return !matchPatterns(ignorePatterns, pathname)
129131
}
130132

131133
return true
@@ -156,10 +158,10 @@ export const robot = (app: Probot) => {
156158
}
157159
try {
158160
const res = await chat?.codeReview(patch);
159-
if (!!res) {
161+
if (!res.lgtm && !!res.review_comment) {
160162
ress.push({
161163
path: file.filename,
162-
body: res,
164+
body: res.review_comment,
163165
position: patch.split('\n').length - 1,
164166
})
165167
}
@@ -172,7 +174,7 @@ export const robot = (app: Probot) => {
172174
repo: repo.repo,
173175
owner: repo.owner,
174176
pull_number: context.pullRequest().pull_number,
175-
body: "Code review by ChatGPT",
177+
body: ress.length ? "Code review by ChatGPT" : "LGTM 👍",
176178
event: 'COMMENT',
177179
commit_id: commits[commits.length - 1].sha,
178180
comments: ress,

src/chat.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,26 @@ export class Chat {
3131
? `Answer me in ${process.env.LANGUAGE},`
3232
: '';
3333

34-
const prompt =
35-
process.env.PROMPT ||
36-
'Below is a code patch, please help me do a brief code review on it. Any bug risks and/or improvement suggestions are welcome:';
34+
const userPrompt = process.env.PROMPT || 'Please review the following code patch. Focus on potential bugs, risks, and improvement suggestions.';
35+
36+
const jsonFormatRequirement = '\nProvide your feedback in a strict JSON format with the following structure:\n' +
37+
'{\n' +
38+
' "lgtm": boolean, // true if the code looks good to merge, false if there are concerns\n' +
39+
' "review_comment": string // Your detailed review comments. You can use markdown syntax in this string, but the overall response must be a valid JSON\n' +
40+
'}\n' +
41+
'Ensure your response is a valid JSON object.\n';
3742

38-
return `${prompt}, ${answerLanguage}:
39-
${patch}
43+
return `${userPrompt}${jsonFormatRequirement} ${answerLanguage}:
44+
${patch}
4045
`;
4146
};
4247

43-
public codeReview = async (patch: string) => {
48+
public codeReview = async (patch: string): Promise<{ lgtm: boolean, review_comment: string }> => {
4449
if (!patch) {
45-
return '';
50+
return {
51+
lgtm: true,
52+
review_comment: ""
53+
};
4654
}
4755

4856
console.time('code-review cost');
@@ -59,14 +67,28 @@ export class Chat {
5967
temperature: +(process.env.temperature || 0) || 1,
6068
top_p: +(process.env.top_p || 0) || 1,
6169
max_tokens: process.env.max_tokens ? +process.env.max_tokens : undefined,
70+
response_format: {
71+
type: "json_object"
72+
},
6273
});
6374

6475
console.timeEnd('code-review cost');
6576

6677
if (res.choices.length) {
67-
return res.choices[0].message.content;
78+
try {
79+
const json = JSON.parse(res.choices[0].message.content || "");
80+
return json
81+
} catch (e) {
82+
return {
83+
lgtm: false,
84+
review_comment: res.choices[0].message.content || ""
85+
}
86+
}
6887
}
6988

70-
return '';
89+
return {
90+
lgtm: true,
91+
review_comment: ""
92+
}
7193
};
7294
}

0 commit comments

Comments
 (0)