mirror of
https://github.com/freeedcom/ai-codereviewer.git
synced 2025-04-21 01:56:47 +00:00
CICO-111286: Include framework as params
This commit is contained in:
parent
3b64b4f5fc
commit
2c508903b4
4 changed files with 97 additions and 86 deletions
|
@ -15,6 +15,10 @@ inputs:
|
||||||
description: "Glob patterns to exclude files from the diff analysis"
|
description: "Glob patterns to exclude files from the diff analysis"
|
||||||
required: false
|
required: false
|
||||||
default: ""
|
default: ""
|
||||||
|
framework:
|
||||||
|
description: 'Framework for specific guidelines'
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
runs:
|
runs:
|
||||||
using: "node16"
|
using: "node16"
|
||||||
main: "dist/index.js"
|
main: "dist/index.js"
|
||||||
|
|
82
dist/index.js
vendored
82
dist/index.js
vendored
|
@ -51,7 +51,7 @@ const minimatch_1 = __importDefault(__nccwpck_require__(2002));
|
||||||
const GITHUB_TOKEN = core.getInput("GITHUB_TOKEN");
|
const GITHUB_TOKEN = core.getInput("GITHUB_TOKEN");
|
||||||
const OPENAI_API_KEY = core.getInput("OPENAI_API_KEY");
|
const OPENAI_API_KEY = core.getInput("OPENAI_API_KEY");
|
||||||
const OPENAI_API_MODEL = core.getInput("OPENAI_API_MODEL");
|
const OPENAI_API_MODEL = core.getInput("OPENAI_API_MODEL");
|
||||||
const FRAMEWORK = core.getInput("framework"); // New input for framework
|
const FRAMEWORK = core.getInput("framework");
|
||||||
const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
|
const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
|
||||||
const openai = new openai_1.default({
|
const openai = new openai_1.default({
|
||||||
apiKey: OPENAI_API_KEY,
|
apiKey: OPENAI_API_KEY,
|
||||||
|
@ -86,23 +86,7 @@ function getDiff(owner, repo, pull_number) {
|
||||||
return response.data;
|
return response.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getExistingComments(owner, repo, pull_number) {
|
function analyzeCode(parsedDiff, prDetails) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const commentsResponse = yield octokit.pulls.listReviewComments({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
pull_number,
|
|
||||||
});
|
|
||||||
return commentsResponse.data
|
|
||||||
.filter(comment => comment.line !== undefined)
|
|
||||||
.map(comment => ({
|
|
||||||
path: comment.path,
|
|
||||||
line: comment.line,
|
|
||||||
body: comment.body,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function analyzeCode(parsedDiff, prDetails, existingComments) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const comments = [];
|
const comments = [];
|
||||||
for (const file of parsedDiff) {
|
for (const file of parsedDiff) {
|
||||||
|
@ -113,13 +97,8 @@ function analyzeCode(parsedDiff, prDetails, existingComments) {
|
||||||
const aiResponse = yield getAIResponse(prompt);
|
const aiResponse = yield getAIResponse(prompt);
|
||||||
if (aiResponse) {
|
if (aiResponse) {
|
||||||
const newComments = createComment(file, chunk, aiResponse);
|
const newComments = createComment(file, chunk, aiResponse);
|
||||||
for (const comment of newComments) {
|
if (newComments) {
|
||||||
const duplicate = existingComments.some(existingComment => existingComment.path === comment.path &&
|
comments.push(...newComments);
|
||||||
existingComment.line === comment.line &&
|
|
||||||
existingComment.body.trim() === comment.body.trim());
|
|
||||||
if (!duplicate) {
|
|
||||||
comments.push(comment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,7 +363,7 @@ ${chunk.changes
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
function getAIResponse(prompt) {
|
function getAIResponse(prompt) {
|
||||||
var _a, _b, _c;
|
var _a, _b;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const queryConfig = {
|
const queryConfig = {
|
||||||
model: OPENAI_API_MODEL,
|
model: OPENAI_API_MODEL,
|
||||||
|
@ -404,8 +383,16 @@ function getAIResponse(prompt) {
|
||||||
// Log the raw response for debugging
|
// Log the raw response for debugging
|
||||||
console.log('Raw response:', JSON.stringify(response, null, 2));
|
console.log('Raw response:', JSON.stringify(response, null, 2));
|
||||||
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()) || "";
|
||||||
// Extract JSON content from Markdown code block
|
let jsonContent = null;
|
||||||
const jsonContent = (_c = res.match(/```json([\s\S]*)```/)) === null || _c === void 0 ? void 0 : _c[1];
|
// Check if the response is in a code block
|
||||||
|
const codeBlockMatch = res.match(/```json([\s\S]*)```/);
|
||||||
|
if (codeBlockMatch) {
|
||||||
|
jsonContent = codeBlockMatch[1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If not, assume the response is direct JSON
|
||||||
|
jsonContent = res;
|
||||||
|
}
|
||||||
if (!jsonContent) {
|
if (!jsonContent) {
|
||||||
console.error("Failed to extract JSON content from response.");
|
console.error("Failed to extract JSON content from response.");
|
||||||
return null;
|
return null;
|
||||||
|
@ -454,13 +441,34 @@ function createComment(file, chunk, aiResponses) {
|
||||||
}
|
}
|
||||||
function createReviewComment(owner, repo, pull_number, comments) {
|
function createReviewComment(owner, repo, pull_number, comments) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
yield octokit.pulls.createReview({
|
const validComments = comments.filter(comment => comment.path && comment.line > 0 && comment.body.trim() !== "");
|
||||||
owner,
|
if (validComments.length === 0) {
|
||||||
repo,
|
console.log("No valid comments to add");
|
||||||
pull_number,
|
return;
|
||||||
comments,
|
}
|
||||||
event: "COMMENT",
|
console.log("Attempting to create review comments:", JSON.stringify(validComments, null, 2));
|
||||||
});
|
for (const comment of validComments) {
|
||||||
|
try {
|
||||||
|
yield octokit.pulls.createReview({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number,
|
||||||
|
body: comment.body,
|
||||||
|
path: comment.path,
|
||||||
|
line: comment.line,
|
||||||
|
event: 'COMMENT',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error("Error creating review comment:", error);
|
||||||
|
console.log("Request data:", {
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number,
|
||||||
|
comment,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function main() {
|
function main() {
|
||||||
|
@ -495,6 +503,7 @@ function main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const parsedDiff = (0, parse_diff_1.default)(diff);
|
const parsedDiff = (0, parse_diff_1.default)(diff);
|
||||||
|
console.log("Parsed Diff:", JSON.stringify(parsedDiff, null, 2)); // Log parsed diff for debugging
|
||||||
const excludePatterns = core
|
const excludePatterns = core
|
||||||
.getInput("exclude")
|
.getInput("exclude")
|
||||||
.split(",")
|
.split(",")
|
||||||
|
@ -502,8 +511,7 @@ function main() {
|
||||||
const filteredDiff = parsedDiff.filter((file) => {
|
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); });
|
return !excludePatterns.some((pattern) => { var _a; return (0, minimatch_1.default)((_a = file.to) !== null && _a !== void 0 ? _a : "", pattern); });
|
||||||
});
|
});
|
||||||
const existingComments = yield getExistingComments(prDetails.owner, prDetails.repo, prDetails.pull_number);
|
const comments = yield analyzeCode(filteredDiff, prDetails);
|
||||||
const comments = yield analyzeCode(filteredDiff, prDetails, existingComments);
|
|
||||||
if (comments.length > 0) {
|
if (comments.length > 0) {
|
||||||
yield createReviewComment(prDetails.owner, prDetails.repo, prDetails.pull_number, comments);
|
yield createReviewComment(prDetails.owner, prDetails.repo, prDetails.pull_number, comments);
|
||||||
}
|
}
|
||||||
|
|
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
95
src/main.ts
95
src/main.ts
|
@ -8,7 +8,7 @@ import minimatch from "minimatch";
|
||||||
const GITHUB_TOKEN: string = core.getInput("GITHUB_TOKEN");
|
const GITHUB_TOKEN: string = core.getInput("GITHUB_TOKEN");
|
||||||
const OPENAI_API_KEY: string = core.getInput("OPENAI_API_KEY");
|
const OPENAI_API_KEY: string = core.getInput("OPENAI_API_KEY");
|
||||||
const OPENAI_API_MODEL: string = core.getInput("OPENAI_API_MODEL");
|
const OPENAI_API_MODEL: string = core.getInput("OPENAI_API_MODEL");
|
||||||
const FRAMEWORK: string = core.getInput("framework"); // New input for framework
|
const FRAMEWORK: string = core.getInput("framework");
|
||||||
|
|
||||||
const octokit = new Octokit({ auth: GITHUB_TOKEN });
|
const octokit = new Octokit({ auth: GITHUB_TOKEN });
|
||||||
|
|
||||||
|
@ -57,29 +57,9 @@ async function getDiff(
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getExistingComments(
|
|
||||||
owner: string,
|
|
||||||
repo: string,
|
|
||||||
pull_number: number
|
|
||||||
): Promise<Array<{ path: string; line: number; body: string }>> {
|
|
||||||
const commentsResponse = await octokit.pulls.listReviewComments({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
pull_number,
|
|
||||||
});
|
|
||||||
return commentsResponse.data
|
|
||||||
.filter(comment => comment.line !== undefined)
|
|
||||||
.map(comment => ({
|
|
||||||
path: comment.path,
|
|
||||||
line: comment.line!,
|
|
||||||
body: comment.body,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function analyzeCode(
|
async function analyzeCode(
|
||||||
parsedDiff: File[],
|
parsedDiff: File[],
|
||||||
prDetails: PRDetails,
|
prDetails: PRDetails
|
||||||
existingComments: Array<{ path: string; line: number; body: string }>
|
|
||||||
): Promise<Array<{ body: string; path: string; line: number }>> {
|
): Promise<Array<{ body: string; path: string; line: number }>> {
|
||||||
const comments: Array<{ body: string; path: string; line: number }> = [];
|
const comments: Array<{ body: string; path: string; line: number }> = [];
|
||||||
|
|
||||||
|
@ -90,16 +70,8 @@ async function analyzeCode(
|
||||||
const aiResponse = await getAIResponse(prompt);
|
const aiResponse = await getAIResponse(prompt);
|
||||||
if (aiResponse) {
|
if (aiResponse) {
|
||||||
const newComments = createComment(file, chunk, aiResponse);
|
const newComments = createComment(file, chunk, aiResponse);
|
||||||
for (const comment of newComments) {
|
if (newComments) {
|
||||||
const duplicate = existingComments.some(
|
comments.push(...newComments);
|
||||||
existingComment =>
|
|
||||||
existingComment.path === comment.path &&
|
|
||||||
existingComment.line === comment.line &&
|
|
||||||
existingComment.body.trim() === comment.body.trim()
|
|
||||||
);
|
|
||||||
if (!duplicate) {
|
|
||||||
comments.push(comment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,8 +368,16 @@ async function getAIResponse(prompt: string): Promise<Array<{
|
||||||
|
|
||||||
const res = response.choices[0].message?.content?.trim() || "";
|
const res = response.choices[0].message?.content?.trim() || "";
|
||||||
|
|
||||||
// Extract JSON content from Markdown code block
|
let jsonContent: string | null = null;
|
||||||
const jsonContent = res.match(/```json([\s\S]*)```/)?.[1];
|
|
||||||
|
// Check if the response is in a code block
|
||||||
|
const codeBlockMatch = res.match(/```json([\s\S]*)```/);
|
||||||
|
if (codeBlockMatch) {
|
||||||
|
jsonContent = codeBlockMatch[1];
|
||||||
|
} else {
|
||||||
|
// If not, assume the response is direct JSON
|
||||||
|
jsonContent = res;
|
||||||
|
}
|
||||||
|
|
||||||
if (!jsonContent) {
|
if (!jsonContent) {
|
||||||
console.error("Failed to extract JSON content from response.");
|
console.error("Failed to extract JSON content from response.");
|
||||||
|
@ -461,13 +441,36 @@ async function createReviewComment(
|
||||||
pull_number: number,
|
pull_number: number,
|
||||||
comments: Array<{ body: string; path: string; line: number }>
|
comments: Array<{ body: string; path: string; line: number }>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await octokit.pulls.createReview({
|
const validComments = comments.filter(comment => comment.path && comment.line > 0 && comment.body.trim() !== "");
|
||||||
owner,
|
|
||||||
repo,
|
if (validComments.length === 0) {
|
||||||
pull_number,
|
console.log("No valid comments to add");
|
||||||
comments,
|
return;
|
||||||
event: "COMMENT",
|
}
|
||||||
});
|
|
||||||
|
console.log("Attempting to create review comments:", JSON.stringify(validComments, null, 2));
|
||||||
|
|
||||||
|
for (const comment of validComments) {
|
||||||
|
try {
|
||||||
|
await octokit.pulls.createReview({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number,
|
||||||
|
body: comment.body,
|
||||||
|
path: comment.path,
|
||||||
|
line: comment.line,
|
||||||
|
event: 'COMMENT',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating review comment:", error);
|
||||||
|
console.log("Request data:", {
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number,
|
||||||
|
comment,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
@ -510,6 +513,8 @@ async function main() {
|
||||||
|
|
||||||
const parsedDiff = parseDiff(diff);
|
const parsedDiff = parseDiff(diff);
|
||||||
|
|
||||||
|
console.log("Parsed Diff:", JSON.stringify(parsedDiff, null, 2)); // Log parsed diff for debugging
|
||||||
|
|
||||||
const excludePatterns = core
|
const excludePatterns = core
|
||||||
.getInput("exclude")
|
.getInput("exclude")
|
||||||
.split(",")
|
.split(",")
|
||||||
|
@ -521,13 +526,7 @@ async function main() {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const existingComments = await getExistingComments(
|
const comments = await analyzeCode(filteredDiff, prDetails);
|
||||||
prDetails.owner,
|
|
||||||
prDetails.repo,
|
|
||||||
prDetails.pull_number
|
|
||||||
);
|
|
||||||
|
|
||||||
const comments = await analyzeCode(filteredDiff, prDetails, existingComments);
|
|
||||||
if (comments.length > 0) {
|
if (comments.length > 0) {
|
||||||
await createReviewComment(
|
await createReviewComment(
|
||||||
prDetails.owner,
|
prDetails.owner,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue