Support push trigger + plenty refactoring [review]

This commit is contained in:
Jimmy Royer 2024-09-18 17:20:23 -04:00
parent 65cf847966
commit e8074efc8b
3 changed files with 442 additions and 134 deletions

301
dist/index.js vendored
View file

@ -157,19 +157,51 @@ require("./sourcemap-register.js");
defaultQuery: { "api-version": OPENAI_API_VERSION }, defaultQuery: { "api-version": OPENAI_API_VERSION },
defaultHeaders: { "api-key": OPENAI_API_KEY }, defaultHeaders: { "api-key": OPENAI_API_KEY },
}); });
function getPRDetails() { /**
* Retrieves pull request details based on the GitHub event type.
*
* This function reads the GitHub event data from the environment, logs it for debugging purposes,
* and then determines the appropriate method to fetch pull request details based on the event type.
* It supports the "opened", "synchronize", and "push" events.
*
* @param {GitHubEvent} event - The type of GitHub event ("opened", "synchronize", or "push").
* @returns {Promise<PRDetails>} - A promise that resolves to the pull request details.
*
* @throws {Error} - Throws an error if the event type is unsupported.
*
* Example usage:
* const prDetails = await getPrDetails("opened");
* console.log(prDetails);
*/
function getPrDetails(event) {
return __awaiter(this, void 0, void 0, function* () {
const eventPath = process.env.GITHUB_EVENT_PATH || "";
const eventData = JSON.parse(
(0, fs_1.readFileSync)(eventPath, "utf8")
);
console.log("GitHub Event Data:", eventData); // Log the event data for debugging
switch (event) {
case "opened":
case "synchronize":
return getPrFromEvent(eventData);
case "push":
return getPrFromApi(eventData);
default:
throw new Error(`Unsupported event: ${event}`);
}
});
}
/**
* Retrieves pull request details from the given event data.
*
* @param eventData - The event data containing repository and pull request number.
* @returns A promise that resolves to the pull request details.
* @throws Will throw an error if the event payload is missing the repository or number.
*/
function getPrFromEvent(eventData) {
var _a, _b; var _a, _b;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
console.log("Fetching pull request details..."); const { repository, number } = eventData;
console.log("GITHUB_EVENT_PATH:", process.env.GITHUB_EVENT_PATH);
console.log("GITHUB_EVENT_NAME:", process.env.GITHUB_EVENT_NAME);
const eventData = JSON.parse(
(0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH || "", "utf8")
);
console.log("Github event data:", eventData);
const { repository, number } = JSON.parse(
(0, fs_1.readFileSync)(process.env.GITHUB_EVENT_PATH || "", "utf8")
);
if (!repository || !number) { if (!repository || !number) {
throw new Error( throw new Error(
"Invalid event payload: missing repository or number" "Invalid event payload: missing repository or number"
@ -191,6 +223,53 @@ require("./sourcemap-register.js");
}; };
}); });
} }
/**
* Retrieves the pull request details associated with a given push event from the GitHub API.
*
* @param eventData - The event data containing information about the push event.
* @returns A promise that resolves to the details of the associated pull request.
* @throws Will throw an error if no associated pull request is found for the given push event.
*/
function getPrFromApi(eventData) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const branchName = eventData.ref.replace("refs/heads/", "");
const repoOwner = eventData.repository.owner.login;
const repoName = eventData.repository.name;
const { data: pullRequests } = yield octokit.pulls.list({
owner: repoOwner,
repo: repoName,
state: "open",
});
const pullRequest = pullRequests.find(
(pr) => pr.head.ref === branchName
);
if (!pullRequest) {
throw new Error(
"No associated pull request found for this push event."
);
}
return {
owner: repoOwner,
repo: repoName,
pull_number: pullRequest.number,
title: pullRequest.title,
description:
(_a = pullRequest.body) !== null && _a !== void 0 ? _a : "",
};
});
}
/**
* Fetches the diff of a pull request from the GitHub repository.
*
* This function uses the GitHub API to retrieve the diff of a specified pull request.
* The diff is returned as a string, or null if the request fails.
*
* @param {string} owner - The owner of the repository.
* @param {string} repo - The name of the repository.
* @param {number} pull_number - The number of the pull request.
* @returns {Promise<string | null>} - A promise that resolves to the diff string or null if the request fails.
*/
function getDiff(owner, repo, pull_number) { function getDiff(owner, repo, pull_number) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const response = yield octokit.pulls.get({ const response = yield octokit.pulls.get({
@ -203,6 +282,23 @@ require("./sourcemap-register.js");
return response.data; return response.data;
}); });
} }
/**
* Analyzes the parsed diff files and generates review comments using AI.
*
* This function iterates over the parsed diff files and their respective chunks,
* identifies valid line numbers for changes, and generates a prompt for the AI to review the code.
* It then filters the AI responses to ensure they correspond to valid line numbers and creates
* review comments based on the AI responses.
*
* @param {File[]} parsedDiff - An array of parsed diff files to be analyzed.
* @param {PRDetails} prDetails - Details of the pull request, including owner, repo, pull number, title, and description.
* @returns {Promise<Array<{ body: string; path: string; line: number }>>} - A promise that resolves to an array of review comments.
*
* Example usage:
* const parsedDiff = parseDiff(diff);
* const prDetails = await getPRDetails();
* const comments = await analyzeCode(parsedDiff, prDetails);
*/
function analyzeCode(parsedDiff, prDetails) { function analyzeCode(parsedDiff, prDetails) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const comments = []; const comments = [];
@ -255,6 +351,14 @@ require("./sourcemap-register.js");
return comments; return comments;
}); });
} }
/**
* Generates a prompt string for reviewing pull requests based on the provided file, chunk, and PR details.
*
* @param {File} file - The file object containing information about the file being reviewed.
* @param {Chunk} chunk - The chunk object containing the diff content and changes.
* @param {PRDetails} prDetails - The pull request details including title and description.
* @returns {string} The generated prompt string for the review task.
*/
function createPrompt(file, chunk, prDetails) { function createPrompt(file, chunk, prDetails) {
return `Your task is to review pull requests. Instructions: return `Your task is to review pull requests. Instructions:
- Provide the response in following JSON format: {"reviews": [{"lineNumber": <line_number>, "reviewComment": "<review comment>"}]} - Provide the response in following JSON format: {"reviews": [{"lineNumber": <line_number>, "reviewComment": "<review comment>"}]}
@ -286,6 +390,16 @@ ${chunk.changes
\`\`\` \`\`\`
`; `;
} }
/**
* Fetches AI-generated review comments for a given prompt.
*
* @param prompt - The input string to be sent to the AI model for generating responses.
* @returns A promise that resolves to an array of review comments, each containing a line number and a review comment, or null if an error occurs.
*
* The function configures the query parameters for the AI model, sends the prompt to the model, and parses the response.
* If the model supports JSON responses, it requests the response in JSON format.
* In case of an error during the API call, it logs the error and returns null.
*/
function getAIResponse(prompt) { function getAIResponse(prompt) {
var _a, _b; var _a, _b;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
@ -331,6 +445,14 @@ ${chunk.changes
} }
}); });
} }
/**
* Generates an array of review comments for a given file and chunk based on AI responses.
*
* @param file - The file object containing information about the file being reviewed.
* @param chunk - The chunk object representing a portion of the file.
* @param aiResponses - An array of AI response objects, each containing a line number and a review comment.
* @returns An array of objects, each representing a review comment with a body, path, and line number.
*/
function createComment(file, chunk, aiResponses) { function createComment(file, chunk, aiResponses) {
return aiResponses.flatMap((aiResponse) => { return aiResponses.flatMap((aiResponse) => {
if (!file.to) { if (!file.to) {
@ -343,6 +465,18 @@ ${chunk.changes
}; };
}); });
} }
/**
* Creates a review comment on a pull request.
*
* @param owner - The owner of the repository.
* @param repo - The name of the repository.
* @param pull_number - The number of the pull request.
* @param comments - An array of comment objects, each containing:
* - `body`: The text of the comment.
* - `path`: The file path to which the comment applies.
* - `line`: The line number in the file where the comment should be placed.
* @returns A promise that resolves when the review comment has been created.
*/
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({ yield octokit.pulls.createReview({
@ -354,11 +488,59 @@ ${chunk.changes
}); });
}); });
} }
/**
* Filters the parsed diff files based on include and exclude patterns.
*
* This function reads the `exclude` and `include` patterns from the GitHub Action inputs,
* trims and filters out any empty strings, and then applies these patterns to the parsed diff files.
* Files that match the exclude patterns are excluded, and files that match the include patterns are included.
* If both patterns are provided, the exclude patterns take precedence over the include patterns.
*
* @param {File[]} parsedDiff - An array of parsed diff files to be filtered.
* @returns {File[]} - An array of filtered diff files.
*
* Example usage:
* const parsedDiff = parseDiff(diff);
* const filteredDiff = filterDiffs(parsedDiff);
*/
function filterDiffs(parsedDiff) {
const excludePatterns = core
.getInput("exclude")
.split(",")
.map((s) => s.trim())
.filter((s) => s.length > 0); // Filter out empty strings;
const includePatterns = core
.getInput("include")
.split(",")
.map((s) => s.trim())
.filter((s) => s.length > 0); // Filter out empty strings;
const filteredDiff = parsedDiff.filter((file) => {
const excluded =
excludePatterns.length > 0 &&
excludePatterns.some((pattern) => {
var _a;
return (0, minimatch_1.default)(
(_a = file.to) !== null && _a !== void 0 ? _a : "",
pattern
);
});
const included =
includePatterns.length === 0 ||
includePatterns.some((pattern) => {
var _a;
return (0, minimatch_1.default)(
(_a = file.to) !== null && _a !== void 0 ? _a : "",
pattern
);
});
// Excluded patterns take precedence over included patterns.
return !excluded && included;
});
return filteredDiff;
}
function main() { function main() {
var _a; var _a;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const prDetails = yield getPRDetails();
let diff;
const eventData = JSON.parse( const eventData = JSON.parse(
(0, fs_1.readFileSync)( (0, fs_1.readFileSync)(
(_a = process.env.GITHUB_EVENT_PATH) !== null && _a !== void 0 (_a = process.env.GITHUB_EVENT_PATH) !== null && _a !== void 0
@ -367,75 +549,48 @@ ${chunk.changes
"utf8" "utf8"
) )
); );
console.log("Github triggered event data:", eventData); console.log("GitHub triggered event data:", eventData);
if (eventData.action === "opened") { const prDetails = yield getPrDetails(eventData);
diff = yield getDiff( if (!prDetails) {
prDetails.owner,
prDetails.repo,
prDetails.pull_number
);
} 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",
},
owner: prDetails.owner,
repo: prDetails.repo,
base: newBaseSha,
head: newHeadSha,
});
diff = String(response.data);
} else if (eventData.action === "placeholder") {
diff = yield getDiff(
prDetails.owner,
prDetails.repo,
prDetails.pull_number
);
} else {
console.log( console.log(
`Unsupported event: action=${eventData.action}, process.env.GITHUB_EVENT_NAME=${process.env.GITHUB_EVENT_NAME}` "No associated pull request found for this push event."
); );
return; return;
} }
let diff;
switch (eventData.action) {
case "opened":
case "push":
diff = yield getDiff(
prDetails.owner,
prDetails.repo,
prDetails.pull_number
);
case "synchronize":
const newBaseSha = eventData.before;
const newHeadSha = eventData.after;
const response = yield octokit.repos.compareCommits({
headers: {
accept: "application/vnd.github.v3.diff",
},
owner: prDetails.owner,
repo: prDetails.repo,
base: newBaseSha,
head: newHeadSha,
});
diff = String(response.data);
default:
console.log(
`Unsupported event: action=${eventData.action}, process.env.GITHUB_EVENT_NAME=${process.env.GITHUB_EVENT_NAME}`
);
return;
}
if (!diff) { if (!diff) {
console.log("No diff found"); console.log("No diff found");
return; return;
} }
const parsedDiff = (0, parse_diff_1.default)(diff); const parsedDiff = (0, parse_diff_1.default)(diff);
const excludePatterns = core const filteredDiff = filterDiffs(parsedDiff);
.getInput("exclude")
.split(",")
.map((s) => s.trim())
.filter((s) => s.length > 0); // Filter out empty strings;
const includePatterns = core
.getInput("include")
.split(",")
.map((s) => s.trim())
.filter((s) => s.length > 0); // Filter out empty strings;
const filteredDiff = parsedDiff.filter((file) => {
const excluded =
excludePatterns.length > 0 &&
excludePatterns.some((pattern) => {
var _a;
return (0, minimatch_1.default)(
(_a = file.to) !== null && _a !== void 0 ? _a : "",
pattern
);
});
const included =
includePatterns.length === 0 ||
includePatterns.some((pattern) => {
var _a;
return (0, minimatch_1.default)(
(_a = file.to) !== null && _a !== void 0 ? _a : "",
pattern
);
});
// Excluded patterns take precedence over included patterns.
return !excluded && included;
});
const comments = yield analyzeCode(filteredDiff, prDetails); const comments = yield analyzeCode(filteredDiff, prDetails);
if (comments.length > 0) { if (comments.length > 0) {
yield createReviewComment( yield createReviewComment(

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View file

@ -59,6 +59,10 @@ const openai = new OpenAI({
defaultHeaders: { "api-key": OPENAI_API_KEY }, defaultHeaders: { "api-key": OPENAI_API_KEY },
}); });
// The supported Github events that this Github action can handle.
type GitHubEvent = "opened" | "synchronize" | "push";
// Data structure to host the details of a pull request.
interface PRDetails { interface PRDetails {
owner: string; owner: string;
repo: string; repo: string;
@ -67,18 +71,48 @@ interface PRDetails {
description: string; description: string;
} }
async function getPRDetails(): Promise<PRDetails> { /**
console.log("Fetching pull request details..."); * Retrieves pull request details based on the GitHub event type.
console.log("GITHUB_EVENT_PATH:", process.env.GITHUB_EVENT_PATH); *
console.log("GITHUB_EVENT_NAME:", process.env.GITHUB_EVENT_NAME); * This function reads the GitHub event data from the environment, logs it for debugging purposes,
const eventData = JSON.parse( * and then determines the appropriate method to fetch pull request details based on the event type.
readFileSync(process.env.GITHUB_EVENT_PATH || "", "utf8") * It supports the "opened", "synchronize", and "push" events.
); *
console.log("Github event data:", eventData); * @param {GitHubEvent} event - The type of GitHub event ("opened", "synchronize", or "push").
* @returns {Promise<PRDetails>} - A promise that resolves to the pull request details.
*
* @throws {Error} - Throws an error if the event type is unsupported.
*
* Example usage:
* const prDetails = await getPrDetails("opened");
* console.log(prDetails);
*/
async function getPrDetails(event: GitHubEvent): Promise<PRDetails> {
const eventPath = process.env.GITHUB_EVENT_PATH || "";
const eventData = JSON.parse(readFileSync(eventPath, "utf8"));
const { repository, number } = JSON.parse( console.log("GitHub Event Data:", eventData); // Log the event data for debugging
readFileSync(process.env.GITHUB_EVENT_PATH || "", "utf8")
); switch (event) {
case "opened":
case "synchronize":
return getPrFromEvent(eventData);
case "push":
return getPrFromApi(eventData);
default:
throw new Error(`Unsupported event: ${event}`);
}
}
/**
* Retrieves pull request details from the given event data.
*
* @param eventData - The event data containing repository and pull request number.
* @returns A promise that resolves to the pull request details.
* @throws Will throw an error if the event payload is missing the repository or number.
*/
async function getPrFromEvent(eventData: any): Promise<PRDetails> {
const { repository, number } = eventData;
if (!repository || !number) { if (!repository || !number) {
throw new Error("Invalid event payload: missing repository or number"); throw new Error("Invalid event payload: missing repository or number");
} }
@ -97,6 +131,50 @@ async function getPRDetails(): Promise<PRDetails> {
}; };
} }
/**
* Retrieves the pull request details associated with a given push event from the GitHub API.
*
* @param eventData - The event data containing information about the push event.
* @returns A promise that resolves to the details of the associated pull request.
* @throws Will throw an error if no associated pull request is found for the given push event.
*/
async function getPrFromApi(eventData: any): Promise<PRDetails> {
const branchName = eventData.ref.replace("refs/heads/", "");
const repoOwner = eventData.repository.owner.login;
const repoName = eventData.repository.name;
const { data: pullRequests } = await octokit.pulls.list({
owner: repoOwner,
repo: repoName,
state: "open",
});
const pullRequest = pullRequests.find((pr) => pr.head.ref === branchName);
if (!pullRequest) {
throw new Error("No associated pull request found for this push event.");
}
return {
owner: repoOwner,
repo: repoName,
pull_number: pullRequest.number,
title: pullRequest.title,
description: pullRequest.body ?? "",
};
}
/**
* Fetches the diff of a pull request from the GitHub repository.
*
* This function uses the GitHub API to retrieve the diff of a specified pull request.
* The diff is returned as a string, or null if the request fails.
*
* @param {string} owner - The owner of the repository.
* @param {string} repo - The name of the repository.
* @param {number} pull_number - The number of the pull request.
* @returns {Promise<string | null>} - A promise that resolves to the diff string or null if the request fails.
*/
async function getDiff( async function getDiff(
owner: string, owner: string,
repo: string, repo: string,
@ -112,6 +190,23 @@ async function getDiff(
return response.data; return response.data;
} }
/**
* Analyzes the parsed diff files and generates review comments using AI.
*
* This function iterates over the parsed diff files and their respective chunks,
* identifies valid line numbers for changes, and generates a prompt for the AI to review the code.
* It then filters the AI responses to ensure they correspond to valid line numbers and creates
* review comments based on the AI responses.
*
* @param {File[]} parsedDiff - An array of parsed diff files to be analyzed.
* @param {PRDetails} prDetails - Details of the pull request, including owner, repo, pull number, title, and description.
* @returns {Promise<Array<{ body: string; path: string; line: number }>>} - A promise that resolves to an array of review comments.
*
* Example usage:
* const parsedDiff = parseDiff(diff);
* const prDetails = await getPRDetails();
* const comments = await analyzeCode(parsedDiff, prDetails);
*/
async function analyzeCode( async function analyzeCode(
parsedDiff: File[], parsedDiff: File[],
prDetails: PRDetails prDetails: PRDetails
@ -158,6 +253,14 @@ async function analyzeCode(
return comments; return comments;
} }
/**
* Generates a prompt string for reviewing pull requests based on the provided file, chunk, and PR details.
*
* @param {File} file - The file object containing information about the file being reviewed.
* @param {Chunk} chunk - The chunk object containing the diff content and changes.
* @param {PRDetails} prDetails - The pull request details including title and description.
* @returns {string} The generated prompt string for the review task.
*/
function createPrompt(file: File, chunk: Chunk, prDetails: PRDetails): string { function createPrompt(file: File, chunk: Chunk, prDetails: PRDetails): string {
return `Your task is to review pull requests. Instructions: return `Your task is to review pull requests. Instructions:
- Provide the response in following JSON format: {"reviews": [{"lineNumber": <line_number>, "reviewComment": "<review comment>"}]} - Provide the response in following JSON format: {"reviews": [{"lineNumber": <line_number>, "reviewComment": "<review comment>"}]}
@ -190,6 +293,16 @@ ${chunk.changes
`; `;
} }
/**
* Fetches AI-generated review comments for a given prompt.
*
* @param prompt - The input string to be sent to the AI model for generating responses.
* @returns A promise that resolves to an array of review comments, each containing a line number and a review comment, or null if an error occurs.
*
* The function configures the query parameters for the AI model, sends the prompt to the model, and parses the response.
* If the model supports JSON responses, it requests the response in JSON format.
* In case of an error during the API call, it logs the error and returns null.
*/
async function getAIResponse(prompt: string): Promise<Array<{ async function getAIResponse(prompt: string): Promise<Array<{
lineNumber: string; lineNumber: string;
reviewComment: string; reviewComment: string;
@ -227,6 +340,14 @@ async function getAIResponse(prompt: string): Promise<Array<{
} }
} }
/**
* Generates an array of review comments for a given file and chunk based on AI responses.
*
* @param file - The file object containing information about the file being reviewed.
* @param chunk - The chunk object representing a portion of the file.
* @param aiResponses - An array of AI response objects, each containing a line number and a review comment.
* @returns An array of objects, each representing a review comment with a body, path, and line number.
*/
function createComment( function createComment(
file: File, file: File,
chunk: Chunk, chunk: Chunk,
@ -247,6 +368,18 @@ function createComment(
}); });
} }
/**
* Creates a review comment on a pull request.
*
* @param owner - The owner of the repository.
* @param repo - The name of the repository.
* @param pull_number - The number of the pull request.
* @param comments - An array of comment objects, each containing:
* - `body`: The text of the comment.
* - `path`: The file path to which the comment applies.
* - `line`: The line number in the file where the comment should be placed.
* @returns A promise that resolves when the review comment has been created.
*/
async function createReviewComment( async function createReviewComment(
owner: string, owner: string,
repo: string, repo: string,
@ -262,55 +395,22 @@ async function createReviewComment(
}); });
} }
async function main() { /**
const prDetails = await getPRDetails(); * Filters the parsed diff files based on include and exclude patterns.
let diff: string | null; *
const eventData = JSON.parse( * This function reads the `exclude` and `include` patterns from the GitHub Action inputs,
readFileSync(process.env.GITHUB_EVENT_PATH ?? "", "utf8") * trims and filters out any empty strings, and then applies these patterns to the parsed diff files.
); * Files that match the exclude patterns are excluded, and files that match the include patterns are included.
* If both patterns are provided, the exclude patterns take precedence over the include patterns.
console.log("Github triggered event data:", eventData); *
if (eventData.action === "opened") { * @param {File[]} parsedDiff - An array of parsed diff files to be filtered.
diff = await getDiff( * @returns {File[]} - An array of filtered diff files.
prDetails.owner, *
prDetails.repo, * Example usage:
prDetails.pull_number * const parsedDiff = parseDiff(diff);
); * const filteredDiff = filterDiffs(parsedDiff);
} else if (eventData.action === "synchronize") { */
const newBaseSha = eventData.before; function filterDiffs(parsedDiff: File[]): File[] {
const newHeadSha = eventData.after;
const response = await octokit.repos.compareCommits({
headers: {
accept: "application/vnd.github.v3.diff",
},
owner: prDetails.owner,
repo: prDetails.repo,
base: newBaseSha,
head: newHeadSha,
});
diff = String(response.data);
} else if (eventData.action === "placeholder") {
diff = await getDiff(
prDetails.owner,
prDetails.repo,
prDetails.pull_number
);
} else {
console.log(
`Unsupported event: action=${eventData.action}, process.env.GITHUB_EVENT_NAME=${process.env.GITHUB_EVENT_NAME}`
);
return;
}
if (!diff) {
console.log("No diff found");
return;
}
const parsedDiff = parseDiff(diff);
const excludePatterns = core const excludePatterns = core
.getInput("exclude") .getInput("exclude")
.split(",") .split(",")
@ -336,6 +436,59 @@ async function main() {
return !excluded && included; return !excluded && included;
}); });
return filteredDiff;
}
async function main() {
const eventData = JSON.parse(
readFileSync(process.env.GITHUB_EVENT_PATH ?? "", "utf8")
);
console.log("GitHub triggered event data:", eventData);
const prDetails = await getPrDetails(eventData);
if (!prDetails) {
console.log("No associated pull request found for this push event.");
return;
}
let diff: string | null;
switch (eventData.action) {
case "opened":
case "push":
diff = await getDiff(
prDetails.owner,
prDetails.repo,
prDetails.pull_number
);
case "synchronize":
const newBaseSha = eventData.before;
const newHeadSha = eventData.after;
const response = await octokit.repos.compareCommits({
headers: {
accept: "application/vnd.github.v3.diff",
},
owner: prDetails.owner,
repo: prDetails.repo,
base: newBaseSha,
head: newHeadSha,
});
diff = String(response.data);
default:
console.log(
`Unsupported event: action=${eventData.action}, process.env.GITHUB_EVENT_NAME=${process.env.GITHUB_EVENT_NAME}`
);
return;
}
if (!diff) {
console.log("No diff found");
return;
}
const parsedDiff = parseDiff(diff);
const filteredDiff = filterDiffs(parsedDiff);
const comments = await analyzeCode(filteredDiff, prDetails); const comments = await analyzeCode(filteredDiff, prDetails);
if (comments.length > 0) { if (comments.length > 0) {
await createReviewComment( await createReviewComment(