Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
96 changes: 52 additions & 44 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,29 @@ const openai_1 = __importDefault(__nccwpck_require__(47));
const rest_1 = __nccwpck_require__(5375);
const parse_diff_1 = __importDefault(__nccwpck_require__(4833));
const minimatch_1 = __importDefault(__nccwpck_require__(2002));
const GITHUB_TOKEN = core.getInput("GITHUB_TOKEN");
const OPENAI_API_KEY = core.getInput("OPENAI_API_KEY");
const OPENAI_API_MODEL = core.getInput("OPENAI_API_MODEL");
const MAX_TOKENS = Number(core.getInput("max_tokens"));
const GITHUB_TOKEN = core.getInput('GITHUB_TOKEN');
const OPENAI_API_KEY = core.getInput('OPENAI_API_KEY');
const OPENAI_API_MODEL = core.getInput('OPENAI_API_MODEL');
const MAX_TOKENS = Number(core.getInput('max_tokens'));
const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
const openai = new openai_1.default({
apiKey: OPENAI_API_KEY,
apiKey: OPENAI_API_KEY
});
function getPRDetails() {
var _a, _b;
return __awaiter(this, void 0, void 0, function* () {
const { repository, number } = JSON.parse((0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH || "", "utf8"));
const { repository, number } = JSON.parse((0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH || '', 'utf8'));
const prResponse = yield octokit.pulls.get({
owner: repository.owner.login,
repo: repository.name,
pull_number: number,
pull_number: number
});
return {
owner: repository.owner.login,
repo: repository.name,
pull_number: number,
title: (_a = prResponse.data.title) !== null && _a !== void 0 ? _a : "",
description: (_b = prResponse.data.body) !== null && _b !== void 0 ? _b : "",
title: (_a = prResponse.data.title) !== null && _a !== void 0 ? _a : '',
description: (_b = prResponse.data.body) !== null && _b !== void 0 ? _b : ''
};
});
}
Expand All @@ -80,7 +80,7 @@ function getDiff(owner, repo, pull_number) {
owner,
repo,
pull_number,
mediaType: { format: "diff" },
mediaType: { format: 'diff' }
});
// @ts-expect-error - response.data is a string
return response.data;
Expand All @@ -90,14 +90,14 @@ function analyzeCode(parsedDiff, prDetails, customPrompts) {
return __awaiter(this, void 0, void 0, function* () {
const comments = [];
for (const file of parsedDiff) {
if (file.to === "/dev/null")
if (file.to === '/dev/null')
continue; // Ignore deleted files
for (const chunk of file.chunks) {
const prompt = createPrompt(file, chunk, prDetails, customPrompts);
const aiResponse = yield getAIResponse(prompt);
console.log(`Prompt = ${prompt}`);
console.log(`Response: ${aiResponse}`);
console.log("---------");
console.log('---------');
if (aiResponse) {
const newComments = createComment(file, chunk, aiResponse);
if (newComments) {
Expand All @@ -120,7 +120,7 @@ function createPrompt(file, chunk, prDetails, customPrompts) {
${customPrompts}

Review the following code diff in the file "${file.to}" and take the pull request title and description into account when writing the response.

Pull request title: ${prDetails.title}
Pull request description:

Expand All @@ -134,8 +134,8 @@ Git diff to review:
${chunk.content}
${chunk.changes
// @ts-expect-error - ln and ln2 exists where needed
.map((c) => `${c.ln ? c.ln : c.ln2} ${c.content}`)
.join("\n")}
.map(c => `${c.ln ? c.ln : c.ln2} ${c.content}`)
.join('\n')}
\`\`\`
`;
}
Expand All @@ -144,39 +144,46 @@ function getAIResponse(prompt) {
return __awaiter(this, void 0, void 0, function* () {
const queryConfig = {
model: OPENAI_API_MODEL,
temperature: 0.2,
max_tokens: MAX_TOKENS,
max_completion_tokens: MAX_TOKENS,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
presence_penalty: 0
};
try {
const response = yield openai.chat.completions.create(Object.assign(Object.assign(Object.assign({}, queryConfig), (OPENAI_API_MODEL === "gpt-4o" || OPENAI_API_MODEL === "gpt-4-turbo-preview" || OPENAI_API_MODEL === "gpt-4-turbo" || OPENAI_API_MODEL === "gpt-3.5-turbo" || OPENAI_API_MODEL === "gpt-4-0125-preview" || OPENAI_API_MODEL === "gpt-4-1106-preview" || OPENAI_API_MODEL === "gpt-3.5-turbo-0125" || OPENAI_API_MODEL === "gpt-3.5-turbo-1106"
? { response_format: { type: "json_object" } }
const response = yield openai.chat.completions.create(Object.assign(Object.assign(Object.assign({}, queryConfig), (OPENAI_API_MODEL === 'o3-mini' ||
OPENAI_API_MODEL === 'gpt-4o' ||
OPENAI_API_MODEL === 'gpt-4-turbo-preview' ||
OPENAI_API_MODEL === 'gpt-4-turbo' ||
OPENAI_API_MODEL === 'gpt-3.5-turbo' ||
OPENAI_API_MODEL === 'gpt-4-0125-preview' ||
OPENAI_API_MODEL === 'gpt-4-1106-preview' ||
OPENAI_API_MODEL === 'gpt-3.5-turbo-0125' ||
OPENAI_API_MODEL === 'gpt-3.5-turbo-1106'
? { response_format: { type: 'json_object' } }
: {})), { messages: [
{
role: "system",
content: prompt,
},
role: 'system',
content: prompt
}
] }));
const res = ((_b = (_a = response.choices[0].message) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.trim()) || "{}";
const res = ((_b = (_a = response.choices[0].message) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.trim()) || '{}';
return JSON.parse(res).reviews;
}
catch (error) {
console.error("Error:", error);
console.error('Error:', error);
return null;
}
});
}
function createComment(file, chunk, aiResponses) {
return aiResponses.flatMap((aiResponse) => {
return aiResponses.flatMap(aiResponse => {
if (!file.to) {
return [];
}
return {
body: aiResponse.reviewComment,
path: file.to,
line: Number(aiResponse.lineNumber),
line: Number(aiResponse.lineNumber)
};
});
}
Expand All @@ -187,7 +194,7 @@ function createReviewComment(owner, repo, pull_number, comments) {
repo,
pull_number,
comments,
event: "COMMENT",
event: 'COMMENT'
});
});
}
Expand All @@ -196,51 +203,52 @@ function main() {
return __awaiter(this, void 0, void 0, function* () {
const prDetails = yield getPRDetails();
let diff;
const eventData = JSON.parse((0, fs_1.readFileSync)((_a = process.env.GITHUB_EVENT_PATH) !== null && _a !== void 0 ? _a : "", "utf8"));
if (eventData.action === "opened") {
const eventData = JSON.parse((0, fs_1.readFileSync)((_a = process.env.GITHUB_EVENT_PATH) !== null && _a !== void 0 ? _a : '', 'utf8'));
if (eventData.action === 'opened') {
diff = yield getDiff(prDetails.owner, prDetails.repo, prDetails.pull_number);
}
else if (eventData.action === "synchronize") {
else if (eventData.action === 'synchronize') {
const newBaseSha = eventData.before;
const newHeadSha = eventData.after;
const response = yield octokit.repos.compareCommits({
headers: {
accept: "application/vnd.github.v3.diff",
accept: 'application/vnd.github.v3.diff'
},
owner: prDetails.owner,
repo: prDetails.repo,
base: newBaseSha,
head: newHeadSha,
head: newHeadSha
});
diff = String(response.data);
}
else {
console.log("Unsupported event:", process.env.GITHUB_EVENT_NAME);
console.log('Unsupported event:', process.env.GITHUB_EVENT_NAME);
return;
}
if (!diff) {
console.log("No diff found");
console.log('No diff found');
return;
}
const parsedDiff = (0, parse_diff_1.default)(diff);
const excludePatterns = core
.getInput("exclude")
.split(",")
.map((s) => s.trim());
const filteredDiff = parsedDiff.filter((file) => {
return !excludePatterns.some((pattern) => { var _a; return (0, minimatch_1.default)((_a = file.to) !== null && _a !== void 0 ? _a : "", pattern); });
.getInput('exclude')
.split(',')
.map(s => s.trim());
const filteredDiff = parsedDiff.filter(file => {
return !excludePatterns.some(pattern => { var _a; return (0, minimatch_1.default)((_a = file.to) !== null && _a !== void 0 ? _a : '', pattern); });
});
const customPrompts = core.getMultilineInput("custom_prompts")
const customPrompts = core
.getMultilineInput('custom_prompts')
.map(customPrompt => `- ${customPrompt}`)
.join("\n");
.join('\n');
const comments = yield analyzeCode(filteredDiff, prDetails, customPrompts);
if (comments.length > 0) {
yield createReviewComment(prDetails.owner, prDetails.repo, prDetails.pull_number, comments);
}
});
}
main().catch((error) => {
console.error("Error:", error);
main().catch(error => {
console.error('Error:', error);
process.exit(1);
});

Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

Loading