Skip to content

feat: AI 리뷰 Gemini 추가 #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 21, 2025
Merged
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
104 changes: 104 additions & 0 deletions .github/workflows/gemini-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Gemini Code Review

on:
push:
branches: [ feat/gemini ]
paths:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feat/gemini 브랜치에 대한 push 이벤트만 처리하도록 수정하는 것이 좋겠습니다. 다른 브랜치에서의 push 이벤트는 의도하지 않은 코드 리뷰를 발생시킬 수 있습니다. 필요하다면 특정 브랜치 패턴을 사용하여 더욱 세밀하게 제어할 수 있습니다.

- 'backend/**'
pull_request:
types: [opened, synchronize]

jobs:
code-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up Node
uses: actions/setup-node@v3

- name: Install GoogleGenerativeAI
run: |
npm install @google/generative-ai

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pull_request 이벤트와 push 이벤트에 대한 처리 로직을 분리하여 가독성을 높이는 것이 좋습니다. 각 이벤트에 대한 처리를 별도의 job으로 정의하면 코드 관리 및 디버깅이 더욱 용이해집니다.


# PR 이벤트에서의 변경사항 처리
- name: Get git diff for PR
if: github.event_name == 'pull_request'
run: |
git fetch origin "${{ github.event.pull_request.base.ref }}"
git fetch origin "${{ github.event.pull_request.head.ref }}"
git diff --unified=0 "origin/${{ github.event.pull_request.base.ref }}" > "diff.txt"
echo "EVENT_TYPE=pull_request" >> $GITHUB_ENV

# Push 이벤트에서의 변경사항 처리
- name: Get git diff for Push
if: github.event_name == 'push'
run: |
git diff --unified=0 HEAD^ HEAD > "diff.txt"
echo "EVENT_TYPE=push" >> $GITHUB_ENV

# Gemini를 사용한 코드 분석
- name: Run Gemini-1.5-flash
id: gemini_review
uses: actions/github-script@v7
with:
script: |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프롬프트 엔지니어링을 개선하여 Gemini에게 더욱 명확한 지침을 제공해야 합니다. 예를 들어, 코드 리뷰에서 중점적으로 살펴봐야 할 부분 (예: 특정 디자인 패턴의 사용 여부, 코드 스타일 준수 여부, 보안 취약점)을 명시적으로 언급하는 것이 좋습니다. 현재 프롬프트는 다소 일반적입니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gemini API Key를 직접 코드에 노출하는 것은 보안상 좋지 않습니다. GitHub Secrets를 사용하는 것은 좋지만, secrets 접근 방식을 개선하여 더욱 안전하게 관리하는 방법을 고려해야 합니다. (예: 필요한 권한만 부여, 엄격한 접근 제어)

const fs = require("fs");
const diff_output = fs.readFileSync("diff.txt",'utf8');

const { GoogleGenerativeAI } = require("@google/generative-ai");
const genAI = new GoogleGenerativeAI("${{ secrets.GEMINI_API_KEY }}");
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash"});

// PR과 Push에 따라 다른 프롬프트 사용
let prompt;
if (process.env.EVENT_TYPE === 'pull_request') {
prompt = `Explain in korean. You are a senior software engineer and need to perform a code review based on the results of a given git diff. Review the changed code from different perspectives and let us know if there are any changes that need to be made. If you see any code that needs to be fixed in the result of the git diff, you need to calculate the exact line number by referring to the "@@ -0,0 +0,0 @@" part. The output format is \[{"path":"{ filepath }", "line": { line }, "text": { review comment }, "side": "RIGHT"}\] format must be respected.\n<git diff>${diff_output}</git diff>`;
} else {
prompt = `Explain in korean. You are a senior software engineer and need to perform a code review based on the results of a given git diff. Provide a detailed review of the code changes, focusing on code quality, readability, performance, and security. Format your response in Markdown with clear headings for each file reviewed.\n<git diff>${diff_output}</git diff>`;
}

const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();

fs.writeFileSync('review_result.txt', text);
console.log('Review results saved!');

# PR 이벤트: 라인별 리뷰 코멘트 추가
- name: Format and add PR review comments
if: env.EVENT_TYPE == 'pull_request'
id: store
run: |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jq 명령어를 사용하여 JSON을 파싱하는 부분은 에러 처리가 없습니다. jq 실행 결과가 예상과 다를 경우 에러를 적절히 처리하고, workflow가 실패하도록 하는 것이 좋습니다. 또한, 파싱된 결과가 항상 올바른 JSON 형식인지 검증하는 로직도 추가해야 합니다.

COMMENT=$(sed '/^```/d' review_result.txt | jq -c .)
echo "comment=$COMMENT" >> $GITHUB_OUTPUT

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GITHUB_OUTPUT에 직접 COMMENT 변수를 저장하는 대신, 더욱 구조적인 방식 (예: JSON 형식)을 사용하는 것이 좋습니다. 이렇게 하면 후속 단계에서 데이터를 더욱 쉽게 처리할 수 있습니다.


- name: Add Pull Request Review Comment
if: env.EVENT_TYPE == 'pull_request'
uses: nbaztec/[email protected]
with:
comments: ${{ steps.store.outputs.comment }}
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]'
allow-repeats: false

# Push 이벤트: 액션 로그에 리뷰 결과 출력 및 아티팩트 업로드
- name: Display review results in workflow log
if: env.EVENT_TYPE == 'push'
run: |
echo "===== Gemini Code Review Results ====="
cat review_result.txt
echo "======================================"

- name: Upload review results as artifact
if: env.EVENT_TYPE == 'push'
uses: actions/upload-artifact@v4
with:
name: gemini-code-review
path: review_result.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Notice extends BaseEntity {
// 관리자 공지사항

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 변경 사항에 대한 주석이 부족합니다. // 관리자 공지사항 주석만으로는 부족하며, 해당 코드가 어떤 기능을 수행하는지, 어떤 목적으로 추가되었는지에 대한 자세한 설명이 필요합니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가된 코드의 스타일이 기존 코드와 일관성이 있는지 확인해야 합니다. 코딩 스타일 가이드라인을 준수하고 있는지 확인하고 필요한 경우 수정해야 합니다.

private String title;
private String content;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading