Skip to content

Commit

Permalink
Merge branch 'master' of github.com:emanuel-braz/github-actions
Browse files Browse the repository at this point in the history
  • Loading branch information
emanuel-braz committed Nov 17, 2023
2 parents 5614c9c + 6f8a532 commit 1020439
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 18 deletions.
1 change: 0 additions & 1 deletion .github/workflows/code-review.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,4 @@ jobs:
exclude: "**/*.json, **/*.md, **/*.g.dart"
append_prompt: |
- Give a maximum of 4 suggestions
- Do not suggest code formatting issues.
- Do not suggest imports issues.
65 changes: 48 additions & 17 deletions code-review/action.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,30 +57,47 @@ async function getDiff(owner, repo, pull_number) {
}

async function analyzeCode(parsedDiff, prDetails) {
const comments = []; //Array<{ body: string; path: string; line: number }>
const allReviews = []; //Array<{ body: string; path: string; line: number }>

for (const file of parsedDiff) {
if (file.to === "/dev/null") continue; // Ignore deleted files
for (const chunk of file.chunks) {

const messages = createMessages(file, chunk, prDetails);
const messages = generateMessages(file, chunk, prDetails);
const aiResponse = await getAIResponse(messages);
if (aiResponse) {
const newComments = createComment(file, chunk, aiResponse);
if (newComments) {
comments.push(...newComments);
if (!isJSON(aiResponse)) {
logger.log(`AI response is not in JSON format: ${aiResponse}`);
createCommentOnPr(aiResponse, prDetails.owner, prDetails.repo, prDetails.pull_number, file.to);
} else {
logger.log(`AI response is in JSON format: ${aiResponse}`);
const reviews = generateReviewsFromJsonArray(file, chunk, aiResponse);
if (reviews) {
allReviews.push(...reviews);
}
}
}
}
}
return comments;
return allReviews;
}

function createMessages(file, chunk, prDetails) {
const instructionJsonFormat = `- Always provide the response in following JSON format: [{"lineNumber": <line_number>, "reviewComment": "<review comment>"}]`;
function isJSON(obj) {
try {
JSON.parse(obj);
return true;
} catch (e) {
return false;
}
}

function generateMessages(file, chunk, prDetails) {

var contentSystemMessage = `You are a senior software engineer and your task is to review pull requests for possible bugs or bad development practices. Follow the instructions below:
- You will provide suggestions only if there are issues or bugs in the code, otherwise return an empty array.
const instructionJsonFormat = `You are a senior software engineer and your task is to review pull requests for possible bugs or bad development practices. Follow the instructions:
- Always provide the response in following JSON format: [{"lineNumber": <line_number>, "reviewComment": "<review comment>"}]
- You will provide suggestions only if there are issues or bugs in the code, otherwise return an empty array.`;

var contentSystemMessage = `
- Do not give positive comments or compliments.
- Don't suggest removing empty line
- Never suggest adding newline at end of file.
Expand All @@ -94,10 +111,10 @@ function createMessages(file, chunk, prDetails) {
contentSystemMessage = overridePrompt;
}

contentSystemMessage = `${contentSystemMessage}\n${instructionJsonFormat}`;
contentSystemMessage = `${instructionJsonFormat}\n${contentSystemMessage}`;

if (appendPrompt) {
contentSystemMessage = `${contentSystemMessage}\n\n${appendPrompt}`;
contentSystemMessage = `${contentSystemMessage}\n${appendPrompt}`;
}

var systemPrompt =
Expand Down Expand Up @@ -141,7 +158,7 @@ async function getAIResponse(messages) {
const chatCompletionParams = new ChatCompletionParams({
messages: messages,
model: OPENAI_API_MODEL,
temperature: 0,
temperature: 0.1,
max_tokens: parseInt(maxTokens),
top_p: 1,
frequency_penalty: 0,
Expand All @@ -153,15 +170,18 @@ async function getAIResponse(messages) {

const result = response?.trim() || "[]";
logger.log(`AI response: ${result}`);
return JSON.parse(result);
return result;
} catch (error) {
console.error("Error:", error);
return null;
}
}

// Array<{ body: string; path: string; line: number }>
function createComment(file, chunk, aiResponses) {
function generateReviewsFromJsonArray(file, chunk, aiResponses) {

aiResponses = JSON.parse(aiResponses);

return aiResponses.flatMap((aiResponse) => {
if (!file.to) {
return [];
Expand All @@ -174,7 +194,7 @@ function createComment(file, chunk, aiResponses) {
});
}

async function createReviewComment(owner, repo, pull_number, comments) {
async function createReviewOnPr(owner, repo, pull_number, comments) {
await octokit.pulls.createReview({
owner,
repo,
Expand All @@ -184,6 +204,17 @@ async function createReviewComment(owner, repo, pull_number, comments) {
});
}

async function createCommentOnPr(body, owner, repo, pull_number, path) {
octokit.pulls.createReview({
owner,
repo,
pull_number,
path,
body,
event: "COMMENT",
});
}

async function main() {

const prDetails = await getPRDetails();
Expand Down Expand Up @@ -233,7 +264,7 @@ async function main() {

const comments = await analyzeCode(filteredDiff, prDetails);
if (comments.length > 0) {
await createReviewComment(
createReviewOnPr(
prDetails.owner,
prDetails.repo,
prDetails.pull_number,
Expand Down

0 comments on commit 1020439

Please sign in to comment.