From c9142a74b7c2cf1caff6018ccd53e489bb8b3bbc Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 02:40:43 +0900 Subject: [PATCH 01/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/code-review.yml | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/code-review.yml diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml new file mode 100644 index 0000000..e84687d --- /dev/null +++ b/.github/workflows/code-review.yml @@ -0,0 +1,39 @@ +name: AI Code Review + +on: + pull_request: + types: [opened, synchronize] + +permissions: + contents: read + pull-requests: write + +jobs: + code-review: + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.11' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install requests + + - name: Check Ollama availability + run: | + curl http://localhost:11434/api/tags + + - name: Run AI Code Review + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "Starting AI Code Review" + export PYTHONPATH=$PYTHONPATH:${{ github.workspace }} + python .github/scripts/ai_code_review.py + echo "AI Code Review completed" \ No newline at end of file From c1b952554feb7e6087286044160ac7be7f12283b Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 02:41:13 +0900 Subject: [PATCH 02/74] =?UTF-8?q?feat(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 .github/scripts/ai_code_review.py diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py new file mode 100644 index 0000000..3da2a75 --- /dev/null +++ b/.github/scripts/ai_code_review.py @@ -0,0 +1,123 @@ +import json +import os +import requests +import logging +from scripts.review_prompt import review_prompt + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + +def get_pr_files(repo, pr_number, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + + logger.debug(f"PR 파일 가져오는 중. URL: {url}") + logger.debug(f"헤더: {headers}") + + try: + response = requests.get(url, headers=headers) + response.raise_for_status() + return response.json() + except requests.RequestException as e: + logger.error(f"PR 파일 가져오기 오류: {str(e)}") + return None + +def review_code(file_content): + prompt = review_prompt.format(code=file_content) + url = 'http://localhost:11434/api/generate' + data = { + "model": "llama3.2", + "prompt": prompt, + "stream": False, + "options": { + "temperature": 0.7, + "top_p": 0.8, + "top_k": 40, + "num_predict": 1024 + } + } + logger.debug(f"코드 리뷰 중. URL: {url}") + logger.debug(f"요청 데이터: {data}") + + try: + response = requests.post(url, json=data) + response.raise_for_status() + return response.json()['response'] + except requests.RequestException as e: + logger.error(f"코드 리뷰 중 오류 발생: {str(e)}") + return f"코드 리뷰 중 발생한 에러: {str(e)}" + +def post_review_comment(repo, pr_number, commit_id, path, position, body, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + data = { + "body": body, + "commit_id": commit_id, + "path": path, + "position": position + } + logger.debug(f"리뷰 코멘트 게시 중. URL: {url}") + logger.debug(f"헤더: {headers}") + logger.debug(f"데이터: {data}") + + try: + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + logger.info("리뷰 코멘트가 성공적으로 게시되었습니다") + except requests.RequestException as e: + logger.error(f"리뷰 코멘트 게시 중 오류 발생: {str(e)}") + logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") + logger.error(f"응답 상태 코드: {e.response.status_code}") + logger.error(f"응답 헤더: {e.response.headers}") + logger.error(f"응답 내용: {e.response.text}") + +def main(): + try: + github_token = os.environ['GITHUB_TOKEN'] + repo = os.environ['GITHUB_REPOSITORY'] + event_path = os.environ['GITHUB_EVENT_PATH'] + + logger.info(f"저장소 리뷰 시작: {repo}") + logger.debug(f"GitHub 토큰 (처음 5자): {github_token[:5]}...") + + with open(event_path) as f: + event = json.load(f) + + pr_number = event['pull_request']['number'] + logger.info(f"PR 번호 리뷰 중: {pr_number}") + + pr_files = get_pr_files(repo, pr_number, github_token) + + if pr_files: + for file in pr_files: + if file['status'] != 'removed': + logger.info(f"파일 리뷰 중: {file['filename']}") + content = requests.get(file['raw_url']).text + review = review_code(content) + + post_review_comment( + repo, + pr_number, + file['sha'], + file['filename'], + file['changes'], + f"AI Code Review:\n\n{review}", + github_token + ) + else: + logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") + except KeyError as e: + logger.error(f"환경 변수가 설정되지 않음: {str(e)}") + except Exception as e: + logger.error(f"예상치 못한 오류 발생: {str(e)}") + +if __name__ == "__main__": + main() From 652d78dbe88e8a3133f77b02c2ba7c0e981ed147 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 02:41:31 +0900 Subject: [PATCH 03/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 scripts/review_prompt.py diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py new file mode 100644 index 0000000..d904462 --- /dev/null +++ b/scripts/review_prompt.py @@ -0,0 +1,20 @@ +review_prompt = """ +다음 코드를 검토하고 아래 기준에 따라 리뷰를 제공해주세요: + +1. Pre-condition Check: + - 함수나 메서드가 올바르게 작동하기 위해 필요한 변수의 상태나 값의 범위를 가지고 있는지 검사 + +2. Runtime Error Check: + - Runtime Error 가능성이 있는 코드를 검사하며, 기타 잠재적 위험을 확인 + +3. Optimization: + - 코드 패치의 최적화 포인트를 검사. 코드가 성능이 떨어진다고 판단되면, 최적화된 코드를 추천 + +4. Security Issue: + - 코드가 심각한 보안 결함을 가진 모듈을 사용하거나 보안 취약점을 포함하고 있는지 검사 + +각 항목에 대해 문제점을 지적하고, 개선 방안을 제시해주세요. + +코드: +{code} +""" \ No newline at end of file From 675820a89165dd932a51187b1b21bbd6ee9c00d8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 03:03:05 +0900 Subject: [PATCH 04/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 파일별 SHA 값에서 최신 커밋 SHA로 수정 close #6 --- .github/scripts/ai_code_review.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 3da2a75..6c86f71 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -25,6 +25,19 @@ def get_pr_files(repo, pr_number, token): except requests.RequestException as e: logger.error(f"PR 파일 가져오기 오류: {str(e)}") return None + +def get_latest_commit_id(repo, pr_number, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + + response = requests.get(url, headers=headers) + response.raise_for_status() + pr_data = response.json() + return pr_data['head']['sha'] def review_code(file_content): prompt = review_prompt.format(code=file_content) @@ -51,7 +64,7 @@ def review_code(file_content): logger.error(f"코드 리뷰 중 오류 발생: {str(e)}") return f"코드 리뷰 중 발생한 에러: {str(e)}" -def post_review_comment(repo, pr_number, commit_id, path, position, body, token): +def post_review_comment(repo, pr_number, commit_sha, path, position, body, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" headers = { "Authorization": f"Bearer {token}", @@ -60,7 +73,7 @@ def post_review_comment(repo, pr_number, commit_id, path, position, body, token) } data = { "body": body, - "commit_id": commit_id, + "commit_id": commit_sha, "path": path, "position": position } @@ -95,6 +108,7 @@ def main(): logger.info(f"PR 번호 리뷰 중: {pr_number}") pr_files = get_pr_files(repo, pr_number, github_token) + latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) if pr_files: for file in pr_files: @@ -106,7 +120,7 @@ def main(): post_review_comment( repo, pr_number, - file['sha'], + latest_commit_id, file['filename'], file['changes'], f"AI Code Review:\n\n{review}", From 58b3ea34528e82eb3fd02f4a739377e2f42fb11f Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 08:20:58 +0900 Subject: [PATCH 05/74] =?UTF-8?q?feat(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - codellama 모델로 변경 - PR 당 하나의 코드리뷰 코멘트 제공 방식으로 변경 --- .github/scripts/ai_code_review.py | 91 +++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 6c86f71..aa60769 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -7,6 +7,22 @@ logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) +def get_pr_content(repo, pr_number, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + + try: + response = requests.get(url, headers=headers) + response.raise_for_status() + return response.json() + except requests.RequestException as e: + logger.error(f"PR 내용 가져오기 오류: {str(e)}") + return None + def get_pr_files(repo, pr_number, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" headers = { @@ -39,18 +55,18 @@ def get_latest_commit_id(repo, pr_number, token): pr_data = response.json() return pr_data['head']['sha'] -def review_code(file_content): - prompt = review_prompt.format(code=file_content) +def review_code(pr_content): + prompt = review_prompt.format(code=pr_content) url = 'http://localhost:11434/api/generate' data = { - "model": "llama3.2", + "model": "codellama", "prompt": prompt, "stream": False, "options": { "temperature": 0.7, "top_p": 0.8, "top_k": 40, - "num_predict": 1024 + "num_predict": 2048 } } logger.debug(f"코드 리뷰 중. URL: {url}") @@ -92,6 +108,22 @@ def post_review_comment(repo, pr_number, commit_sha, path, position, body, token logger.error(f"응답 헤더: {e.response.headers}") logger.error(f"응답 내용: {e.response.text}") +def post_pr_comment(repo, pr_number, body, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + data = {"body": body} + try: + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + logger.info("성공적으로 PR 코멘트가 게시되었습니다.") + except requests.RequestException as e: + logger.error(f"PR 코멘트 게시 중 오류 발생: {str(e)}") + logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") + def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -107,27 +139,38 @@ def main(): pr_number = event['pull_request']['number'] logger.info(f"PR 번호 리뷰 중: {pr_number}") - pr_files = get_pr_files(repo, pr_number, github_token) - latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) - - if pr_files: - for file in pr_files: - if file['status'] != 'removed': - logger.info(f"파일 리뷰 중: {file['filename']}") - content = requests.get(file['raw_url']).text - review = review_code(content) - - post_review_comment( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['changes'], - f"AI Code Review:\n\n{review}", - github_token - ) + # pr_files = get_pr_files(repo, pr_number, github_token) + # latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) + + pr_content = get_pr_content(repo, pr_number, github_token) + + # 파일 단위 코드 리뷰 로직 + # if pr_files: + # for file in pr_files: + # if file['status'] != 'removed': + # logger.info(f"파일 리뷰 중: {file['filename']}") + # content = requests.get(file['raw_url']).text + # review = review_code(content) + + # post_review_comment( + # repo, + # pr_number, + # latest_commit_id, + # file['filename'], + # file['changes'], + # f"AI Code Review:\n\n{review}", + # github_token + # ) + # else: + # logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") + + if pr_content: + review = review_code(pr_content) + comment_body = f"AI Code Review:\n\n{review}" + post_pr_comment(repo, pr_number, comment_body, github_token) else: - logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") + logger.warning("PR 내용을 가져오는 데 실패했습니다.") + except KeyError as e: logger.error(f"환경 변수가 설정되지 않음: {str(e)}") except Exception as e: From de6ce5e53810e9451ce75c1833b8cfed9f614861 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 08:28:02 +0900 Subject: [PATCH 06/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/code-review.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index e84687d..804f93b 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -15,15 +15,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.11' - - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install requests + python3 -m pip install --upgrade pip + pip3 install requests - name: Check Ollama availability run: | From 7a70d85dfd28e20ecd802b11840455d95a6c6538 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 08:35:30 +0900 Subject: [PATCH 07/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - python 버전 변경 --- .github/workflows/code-review.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 804f93b..2df6076 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -15,10 +15,15 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install dependencies run: | - python3 -m pip install --upgrade pip - pip3 install requests + python -m pip install --upgrade pip + pip install requests - name: Check Ollama availability run: | From eae19162bda77d54225b86f0c543cf3916f50b16 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 08:39:24 +0900 Subject: [PATCH 08/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/code-review.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 2df6076..123634e 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -15,15 +15,13 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.x' + - name: Set Python Path + run: echo "PYTHON_PATH=$(which python3)" >> $GITHUB_ENV - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install requests + ${{ env.PYTHON_PATH }} -m pip install --upgrade pip + ${{ env.PYTHON_PATH }} -m pip install requests - name: Check Ollama availability run: | From 1b0b481841e88d96e6008154c25bf565547533f8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 08:40:41 +0900 Subject: [PATCH 09/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/code-review.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 123634e..834bc4c 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -15,13 +15,15 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set Python Path - run: echo "PYTHON_PATH=$(which python3)" >> $GITHUB_ENV + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.12' - name: Install dependencies run: | - ${{ env.PYTHON_PATH }} -m pip install --upgrade pip - ${{ env.PYTHON_PATH }} -m pip install requests + python -m pip install --upgrade pip + pip install requests - name: Check Ollama availability run: | From a6b6e45c608c24859c133b66534b988ac81658f7 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 08:58:34 +0900 Subject: [PATCH 10/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - self-hosted 경로 설정 --- .github/workflows/code-review.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 834bc4c..52d212d 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -15,11 +15,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.12' - - name: Install dependencies run: | python -m pip install --upgrade pip @@ -29,11 +24,16 @@ jobs: run: | curl http://localhost:11434/api/tags + - name: Check Python version + run: | + python3 --version + which python3 + - name: Run AI Code Review env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Starting AI Code Review" export PYTHONPATH=$PYTHONPATH:${{ github.workspace }} - python .github/scripts/ai_code_review.py + /usr/local/bin/python3 /Users/jonghyunjung/VisualStudioProjects/neonadeuli-main/.github/scripts/ai_code_review.py echo "AI Code Review completed" \ No newline at end of file From fecf1bc72b5b0be047bf81df09447ad28829f488 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 09:02:30 +0900 Subject: [PATCH 11/74] =?UTF-8?q?chore(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/code-review.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 52d212d..a446bd4 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -15,10 +15,13 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set Python Path + run: echo "PYTHON_PATH=$(which python3)" >> $GITHUB_ENV + - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install requests + ${{ env.PYTHON_PATH }} -m pip install --upgrade pip + ${{ env.PYTHON_PATH }} -m pip install requests - name: Check Ollama availability run: | From c03fbd7af3ee0ea59f4440f3006392f5fccbcc9e Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 10:26:50 +0900 Subject: [PATCH 12/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 파일 별 리뷰 코멘트를 모아 다시 하나의 리뷰 코멘트로 요약 --- .github/scripts/ai_code_review.py | 100 +++++++++++------------------- 1 file changed, 36 insertions(+), 64 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index aa60769..00bd567 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -7,22 +7,6 @@ logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) -def get_pr_content(repo, pr_number, token): - url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" - headers = { - "Authorization": f"Bearer {token}", - "Accept": "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28" - } - - try: - response = requests.get(url, headers=headers) - response.raise_for_status() - return response.json() - except requests.RequestException as e: - logger.error(f"PR 내용 가져오기 오류: {str(e)}") - return None - def get_pr_files(repo, pr_number, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" headers = { @@ -63,10 +47,14 @@ def review_code(pr_content): "prompt": prompt, "stream": False, "options": { - "temperature": 0.7, - "top_p": 0.8, + "temperature": 0.5, + "top_p": 0.9, "top_k": 40, - "num_predict": 2048 + "num_predict": 1024, + "repeat_penalty": 1.1, + "presence_penalty": 0.1, + "frequency_penalty": 0.1, + "stop": ["\n\n", "END OF REVIEW"] } } logger.debug(f"코드 리뷰 중. URL: {url}") @@ -108,21 +96,10 @@ def post_review_comment(repo, pr_number, commit_sha, path, position, body, token logger.error(f"응답 헤더: {e.response.headers}") logger.error(f"응답 내용: {e.response.text}") -def post_pr_comment(repo, pr_number, body, token): - url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" - headers = { - "Authorization": f"Bearer {token}", - "Accept": "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28" - } - data = {"body": body} - try: - response = requests.post(url, headers=headers, json=data) - response.raise_for_status() - logger.info("성공적으로 PR 코멘트가 게시되었습니다.") - except requests.RequestException as e: - logger.error(f"PR 코멘트 게시 중 오류 발생: {str(e)}") - logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") +def summarize_reviews(all_reviews): + summary_prompt = f"다음은 여러 파일에 대한 코드 리뷰 결과입니다. 이를 간결하고 통합된 하나의 리뷰 코멘트로 요약해주세요:\n\n{''.join(all_reviews)}" + summary = review_code(summary_prompt) + return summary def main(): try: @@ -139,37 +116,32 @@ def main(): pr_number = event['pull_request']['number'] logger.info(f"PR 번호 리뷰 중: {pr_number}") - # pr_files = get_pr_files(repo, pr_number, github_token) - # latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) - - pr_content = get_pr_content(repo, pr_number, github_token) - - # 파일 단위 코드 리뷰 로직 - # if pr_files: - # for file in pr_files: - # if file['status'] != 'removed': - # logger.info(f"파일 리뷰 중: {file['filename']}") - # content = requests.get(file['raw_url']).text - # review = review_code(content) - - # post_review_comment( - # repo, - # pr_number, - # latest_commit_id, - # file['filename'], - # file['changes'], - # f"AI Code Review:\n\n{review}", - # github_token - # ) - # else: - # logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") - - if pr_content: - review = review_code(pr_content) - comment_body = f"AI Code Review:\n\n{review}" - post_pr_comment(repo, pr_number, comment_body, github_token) + pr_files = get_pr_files(repo, pr_number, github_token) + latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) + + all_reviews = [] + + if pr_files: + for file in pr_files: + if file['status'] != 'removed': + logger.info(f"파일 리뷰 중: {file['filename']}") + content = requests.get(file['raw_url']).text + review = review_code(content) + all_reviews.append(f"File: {file['filename']}\n{review}\n\n") + + combined_review = summarize_reviews(all_reviews) + + post_review_comment( + repo, + pr_number, + latest_commit_id, + None, + None, + f"AI Code Review 요약:\n\n{combined_review}", + github_token + ) else: - logger.warning("PR 내용을 가져오는 데 실패했습니다.") + logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") except KeyError as e: logger.error(f"환경 변수가 설정되지 않음: {str(e)}") From f83c6912031bbcbfb4ea52e68cfef35ce6bccebc Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 10:42:38 +0900 Subject: [PATCH 13/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 43 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 00bd567..5a86efb 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -101,6 +101,23 @@ def summarize_reviews(all_reviews): summary = review_code(summary_prompt) return summary +def post_pr_comment(repo, pr_number, body, token): + url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + data = {"body": body} + + try: + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + logger.info("PR 코멘트가 성공적으로 게시되었습니다.") + except requests.RequestException as e: + logger.error(f"PR 코멘트 게시 중 오류 발생: {str(e)}") + logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") + def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -117,7 +134,7 @@ def main(): logger.info(f"PR 번호 리뷰 중: {pr_number}") pr_files = get_pr_files(repo, pr_number, github_token) - latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) + # latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) all_reviews = [] @@ -131,15 +148,23 @@ def main(): combined_review = summarize_reviews(all_reviews) - post_review_comment( - repo, - pr_number, - latest_commit_id, - None, - None, - f"AI Code Review 요약:\n\n{combined_review}", - github_token + # post_review_comment( + # repo, + # pr_number, + # latest_commit_id, + # file['filename'], + # file['changes'], + # f"AI Code Review:\n\n{review}", + # github_token + # ) + + post_pr_comment( + repo, + pr_number, + f"AI Code Review 요약:\n\n{combined_review}", + github_token ) + else: logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") From 2cae80750521ffe31c75b60bc034bdbb4d40fe1b Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 10:52:41 +0900 Subject: [PATCH 14/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 모델 파라미터 값 수정 --- .github/scripts/ai_code_review.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 5a86efb..c476101 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -47,14 +47,10 @@ def review_code(pr_content): "prompt": prompt, "stream": False, "options": { - "temperature": 0.5, - "top_p": 0.9, + "temperature": 0.7, + "top_p": 0.8, "top_k": 40, - "num_predict": 1024, - "repeat_penalty": 1.1, - "presence_penalty": 0.1, - "frequency_penalty": 0.1, - "stop": ["\n\n", "END OF REVIEW"] + "num_predict": 1024 } } logger.debug(f"코드 리뷰 중. URL: {url}") From 21400390548dde128fac47c1c4872d56d590b5a7 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Sat, 5 Oct 2024 17:37:18 +0900 Subject: [PATCH 15/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - llama3.1 8B 모델로 변경 --- .github/scripts/ai_code_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index c476101..9f7db88 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -43,7 +43,7 @@ def review_code(pr_content): prompt = review_prompt.format(code=pr_content) url = 'http://localhost:11434/api/generate' data = { - "model": "codellama", + "model": "llama3.1", "prompt": prompt, "stream": False, "options": { From c5a642b70dcdb85cbccf0c8b496c8c152f72f348 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Mon, 7 Oct 2024 23:09:20 +0900 Subject: [PATCH 16/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 중요 파일 상세 라인별 코멘트 추가 --- .github/scripts/ai_code_review.py | 101 +++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 7 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 9f7db88..397c30e 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -1,6 +1,7 @@ import json import os import requests +import re import logging from scripts.review_prompt import review_prompt @@ -93,7 +94,7 @@ def post_review_comment(repo, pr_number, commit_sha, path, position, body, token logger.error(f"응답 내용: {e.response.text}") def summarize_reviews(all_reviews): - summary_prompt = f"다음은 여러 파일에 대한 코드 리뷰 결과입니다. 이를 간결하고 통합된 하나의 리뷰 코멘트로 요약해주세요:\n\n{''.join(all_reviews)}" + summary_prompt = f"다음은 전체적인 코드 리뷰 결과입니다 : \n\n{''.join(all_reviews)}" summary = review_code(summary_prompt) return summary @@ -114,6 +115,70 @@ def post_pr_comment(repo, pr_number, body, token): logger.error(f"PR 코멘트 게시 중 오류 발생: {str(e)}") logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") +def post_line_comments(repo, pr_number, commit_sha, filename, patch, line_comments, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + + def get_line_numbers(patch): + lines = patch.split('\n') + line_numbers = [] + current_line = 0 + for line in lines: + if line.startswith('@@'): + current_line = int(line.split('+')[1].split(',')[0]) - 1 + elif not line.startswith('-'): + current_line += 1 + if line.startswith('+'): + line_numbers.append(current_line) + return line_numbers + + def post_single_comment(line_num, comment_text, position): + data = { + "body": comment_text.strip(), + "commit_id": commit_sha, + "path": filename, + "line": position + } + logger.debug(f"라인 {line_num}에 리뷰 코멘트 게시 중. URL: {url}") + logger.debug(f"헤더: {headers}") + logger.debug(f"데이터: {data}") + + try: + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + logger.info(f"라인 {line_num}에 리뷰 코멘트가 성공적으로 게시되었습니다") + except requests.RequestException as e: + logger.error(f"라인 {line_num} 리뷰 코멘트 게시 중 오류 발생: {str(e)}") + logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") + logger.error(f"응답 상태 코드: {e.response.status_code if 'response' in locals() else '알 수 없음'}") + logger.error(f"응답 헤더: {e.response.headers if 'response' in locals() else '알 수 없음'}") + logger.error(f"응답 내용: {e.response.text if 'response' in locals() else '알 수 없음'}") + + line_numbers = get_line_numbers(patch) + + # 라인 코멘트 파싱 및 게시 + for comment in line_comments.split('\n'): + match = re.match(r'(\d+):\s*(.*)', comment) + if match: + line_num, comment_text = match.groups() + try: + line_num = int(line_num) + if 0 <= line_num - 1 < len(line_numbers): + position = line_numbers[line_num - 1] + post_single_comment(line_num, comment_text, position) + else: + logger.warning(f"라인 {line_num}이 유효한 범위를 벗어났습니다.") + except ValueError: + logger.warning(f"잘못된 라인 번호 형식: {line_num}") + else: + logger.warning(f"파싱할 수 없는 코멘트 형식: {comment}") + + logger.info("모든 라인 코멘트 처리 완료") + def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -130,19 +195,41 @@ def main(): logger.info(f"PR 번호 리뷰 중: {pr_number}") pr_files = get_pr_files(repo, pr_number, github_token) - # latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) + latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) - all_reviews = [] + all_code = "" if pr_files: + important_files = [f for f in pr_files if f['changes'] > 50 or f['filename'].endswith('.py')] + for file in pr_files: if file['status'] != 'removed': logger.info(f"파일 리뷰 중: {file['filename']}") content = requests.get(file['raw_url']).text - review = review_code(content) - all_reviews.append(f"File: {file['filename']}\n{review}\n\n") + all_code += f"File: {file['filename']}\n{content}\n\n" + + # 전체 코드에 대한 간략한 리뷰 + overall_review = summarize_reviews(all_code) + + # 중요 파일에 대한 상세 리뷰 + detailed_reviews = [] + for file, content in important_files: + content = requests.get(file['raw_url']).text + review = review_code(content) + detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + + post_line_comments( + repo, + pr_number, + latest_commit_id, + file['filename'], + file['patch'], + review, + github_token + ) - combined_review = summarize_reviews(all_reviews) + # 전체 요약 생성 + final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" # post_review_comment( # repo, @@ -157,7 +244,7 @@ def main(): post_pr_comment( repo, pr_number, - f"AI Code Review 요약:\n\n{combined_review}", + final_summary, github_token ) From 40c9adbba5d67cb9bb228acd426cbddb46d8813b Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Mon, 7 Oct 2024 23:19:32 +0900 Subject: [PATCH 17/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 397c30e..82b10f9 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -213,11 +213,14 @@ def main(): # 중요 파일에 대한 상세 리뷰 detailed_reviews = [] - for file, content in important_files: + for file in important_files: content = requests.get(file['raw_url']).text review = review_code(content) detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + line_comments = review_code(line_comments_prompt) + post_line_comments( repo, pr_number, @@ -249,7 +252,7 @@ def main(): ) else: - logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") + logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") except KeyError as e: logger.error(f"환경 변수가 설정되지 않음: {str(e)}") From cbe72ca7f01c77927929fccaea624476d015c468 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Mon, 7 Oct 2024 23:43:42 +0900 Subject: [PATCH 18/74] =?UTF-8?q?test(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/review-test/data_processor.py | 12 ++++++++++++ .github/scripts/review-test/main.py | 12 ++++++++++++ .github/scripts/review-test/test_utils.py | 16 ++++++++++++++++ .github/scripts/review-test/utils.py | 18 ++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 .github/scripts/review-test/data_processor.py create mode 100644 .github/scripts/review-test/main.py create mode 100644 .github/scripts/review-test/test_utils.py create mode 100644 .github/scripts/review-test/utils.py diff --git a/.github/scripts/review-test/data_processor.py b/.github/scripts/review-test/data_processor.py new file mode 100644 index 0000000..1cd522c --- /dev/null +++ b/.github/scripts/review-test/data_processor.py @@ -0,0 +1,12 @@ +def process_data(data): + processed = [] + for i in range(len(data)): + processed.append(data[i] * 2) + return processed + +def filter_data(data, threshold): + filtered = [] + for item in data: + if item > threshold: + filtered.append(item) + return filtered \ No newline at end of file diff --git a/.github/scripts/review-test/main.py b/.github/scripts/review-test/main.py new file mode 100644 index 0000000..455604f --- /dev/null +++ b/.github/scripts/review-test/main.py @@ -0,0 +1,12 @@ +from data_processor import process_data +from utils import calculate_average, format_output + +def main(): + data = [1, 2, 3, 4, 5] + processed_data = process_data(data) + average = calculate_average(processed_data) + formatted_output = format_output(average) + print(formatted_output) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/.github/scripts/review-test/test_utils.py b/.github/scripts/review-test/test_utils.py new file mode 100644 index 0000000..eb2d9da --- /dev/null +++ b/.github/scripts/review-test/test_utils.py @@ -0,0 +1,16 @@ +import unittest +from utils import calculate_average, is_prime + +class TestUtils(unittest.TestCase): + def test_calculate_average(self): + self.assertEqual(calculate_average([1, 2, 3, 4, 5]), 3) + self.assertEqual(calculate_average([]), 0) + + def test_is_prime(self): + self.assertTrue(is_prime(2)) + self.assertTrue(is_prime(17)) + self.assertFalse(is_prime(4)) + self.assertFalse(is_prime(1)) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/.github/scripts/review-test/utils.py b/.github/scripts/review-test/utils.py new file mode 100644 index 0000000..821b974 --- /dev/null +++ b/.github/scripts/review-test/utils.py @@ -0,0 +1,18 @@ +def calculate_average(numbers): + total = 0 + count = 0 + for num in numbers: + total += num + count += 1 + return total / count if count > 0 else 0 + +def format_output(value): + return f"The result is: {value:.2f}" + +def is_prime(n): + if n < 2: + return False + for i in range(2, n): + if n % i == 0: + return False + return True \ No newline at end of file From eae54028861e1b1691f30befcb23d829c8193d98 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 00:22:59 +0900 Subject: [PATCH 19/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 91 ++++++++++++++++++------------- scripts/review_prompt.py | 30 +++++----- 2 files changed, 67 insertions(+), 54 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 82b10f9..f76f417 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -179,6 +179,38 @@ def post_single_comment(line_num, comment_text, position): logger.info("모든 라인 코멘트 처리 완료") +def parse_review_result(review_result): + result = { + 'overall_review': '', + 'file_reviews': {} + } + + # 전체 리뷰 추출 + overall_match = re.search(r'1\. 전체 리뷰:(.*?)2\. 중요 파일 상세 리뷰:', review_result, re.DOTALL) + if overall_match: + result['overall_review'] = overall_match.group(1).strip() + + # 파일별 리뷰 추출 + file_reviews = re.findall(r'\[([^\]]+)\]:\n(.*?)(?=\n\[|$)', review_result, re.DOTALL) + + for filename, review_content in file_reviews: + result['file_reviews'][filename] = { + 'overall_review': '', + 'line_comments': {} + } + + # 파일별 전반적인 리뷰 추출 + file_overall_match = re.search(r'- 전반적인 리뷰:(.*?)- 라인별 코멘트:', review_content, re.DOTALL) + if file_overall_match: + result['file_reviews'][filename]['overall_review'] = file_overall_match.group(1).strip() + + # 라인별 코멘트 추출 + line_comments = re.findall(r'(\d+):\s*(.+?)(?=\n\d+:|\n\[|$)', review_content, re.DOTALL) + for line_num, comment in line_comments: + result['file_reviews'][filename]['line_comments'][int(line_num)] = comment.strip() + + return result + def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -198,59 +230,40 @@ def main(): latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) all_code = "" + important_files_content = {} if pr_files: - important_files = [f for f in pr_files if f['changes'] > 50 or f['filename'].endswith('.py')] + important_files = [f for f in pr_files if f['changes'] > 50] for file in pr_files: if file['status'] != 'removed': logger.info(f"파일 리뷰 중: {file['filename']}") content = requests.get(file['raw_url']).text all_code += f"File: {file['filename']}\n{content}\n\n" + if file in important_files: + important_files_content[file['filename']] = content - # 전체 코드에 대한 간략한 리뷰 - overall_review = summarize_reviews(all_code) - - # 중요 파일에 대한 상세 리뷰 - detailed_reviews = [] - for file in important_files: - content = requests.get(file['raw_url']).text - review = review_code(content) - detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + # 전체 코드에 대한 리뷰 및 중요 파일에 대한 상세 리뷰 요청 + review_result = review_code(review_prompt) - line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" - line_comments = review_code(line_comments_prompt) + # 리뷰 결과 파싱 및 처리 + parsed_result = parse_review_result(review_result) + + # 전체 PR에 대한 코멘트 게시 + post_pr_comment(repo, pr_number, parsed_result['overall_review'], github_token) + # 중요 파일에 대한 상세 리뷰 + for filename, file_review in parsed_result['file_reviews'].items(): + file_info = next(f for f in important_files if f['filename'] == filename) post_line_comments( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['patch'], - review, + repo, + pr_number, + latest_commit_id, + filename, + file_info['patch'], + file_review['line_comments'], github_token ) - - # 전체 요약 생성 - final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" - - # post_review_comment( - # repo, - # pr_number, - # latest_commit_id, - # file['filename'], - # file['changes'], - # f"AI Code Review:\n\n{review}", - # github_token - # ) - - post_pr_comment( - repo, - pr_number, - final_summary, - github_token - ) - else: logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index d904462..1b5c612 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,20 +1,20 @@ review_prompt = """ -다음 코드를 검토하고 아래 기준에 따라 리뷰를 제공해주세요: +전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: -1. Pre-condition Check: - - 함수나 메서드가 올바르게 작동하기 위해 필요한 변수의 상태나 값의 범위를 가지고 있는지 검사 +전체 코드: +{all_code} -2. Runtime Error Check: - - Runtime Error 가능성이 있는 코드를 검사하며, 기타 잠재적 위험을 확인 +중요 파일들: +{json.dumps(important_files_content, indent=2)} -3. Optimization: - - 코드 패치의 최적화 포인트를 검사. 코드가 성능이 떨어진다고 판단되면, 최적화된 코드를 추천 - -4. Security Issue: - - 코드가 심각한 보안 결함을 가진 모듈을 사용하거나 보안 취약점을 포함하고 있는지 검사 - -각 항목에 대해 문제점을 지적하고, 개선 방안을 제시해주세요. - -코드: -{code} +응답 형식: +1. 전체 리뷰: [여기에 전체 리뷰 내용] +2. 중요 파일 상세 리뷰: + [파일명1]: + - 전반적인 리뷰: [리뷰 내용] + - 라인별 코멘트: + [라인 번호]: [코멘트] + ... + [파일명2]: + ... """ \ No newline at end of file From d310b4ca936c357b418b2c1725195fe288d7a2d5 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 00:29:12 +0900 Subject: [PATCH 20/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 4 ++-- scripts/review_prompt.py | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index f76f417..9b1f7d4 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -3,7 +3,7 @@ import requests import re import logging -from scripts.review_prompt import review_prompt +from scripts.review_prompt import generate_review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -244,7 +244,7 @@ def main(): important_files_content[file['filename']] = content # 전체 코드에 대한 리뷰 및 중요 파일에 대한 상세 리뷰 요청 - review_result = review_code(review_prompt) + review_result = generate_review_prompt(all_code, important_files_content) # 리뷰 결과 파싱 및 처리 parsed_result = parse_review_result(review_result) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 1b5c612..807ccea 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,11 +1,12 @@ -review_prompt = """ -전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: +import json + +REVIEW_PROMPT_TEMPLATE = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: 전체 코드: {all_code} 중요 파일들: -{json.dumps(important_files_content, indent=2)} +{important_files} 응답 형식: 1. 전체 리뷰: [여기에 전체 리뷰 내용] @@ -17,4 +18,10 @@ ... [파일명2]: ... -""" \ No newline at end of file +""" + +def generate_review_prompt(all_code, important_files_content): + return REVIEW_PROMPT_TEMPLATE.format( + all_code=all_code, + important_files=json.dumps(important_files_content, indent=2) + ) \ No newline at end of file From 9c0209efa446072bc9eb3436d0071e65e555bd3e Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 01:06:15 +0900 Subject: [PATCH 21/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 81 +++++++++++-------------------- scripts/review_prompt.py | 4 +- 2 files changed, 30 insertions(+), 55 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 9b1f7d4..1938ebe 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -3,7 +3,7 @@ import requests import re import logging -from scripts.review_prompt import generate_review_prompt +from scripts.review_prompt import review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -179,38 +179,6 @@ def post_single_comment(line_num, comment_text, position): logger.info("모든 라인 코멘트 처리 완료") -def parse_review_result(review_result): - result = { - 'overall_review': '', - 'file_reviews': {} - } - - # 전체 리뷰 추출 - overall_match = re.search(r'1\. 전체 리뷰:(.*?)2\. 중요 파일 상세 리뷰:', review_result, re.DOTALL) - if overall_match: - result['overall_review'] = overall_match.group(1).strip() - - # 파일별 리뷰 추출 - file_reviews = re.findall(r'\[([^\]]+)\]:\n(.*?)(?=\n\[|$)', review_result, re.DOTALL) - - for filename, review_content in file_reviews: - result['file_reviews'][filename] = { - 'overall_review': '', - 'line_comments': {} - } - - # 파일별 전반적인 리뷰 추출 - file_overall_match = re.search(r'- 전반적인 리뷰:(.*?)- 라인별 코멘트:', review_content, re.DOTALL) - if file_overall_match: - result['file_reviews'][filename]['overall_review'] = file_overall_match.group(1).strip() - - # 라인별 코멘트 추출 - line_comments = re.findall(r'(\d+):\s*(.+?)(?=\n\d+:|\n\[|$)', review_content, re.DOTALL) - for line_num, comment in line_comments: - result['file_reviews'][filename]['line_comments'][int(line_num)] = comment.strip() - - return result - def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -230,7 +198,6 @@ def main(): latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) all_code = "" - important_files_content = {} if pr_files: important_files = [f for f in pr_files if f['changes'] > 50] @@ -240,30 +207,40 @@ def main(): logger.info(f"파일 리뷰 중: {file['filename']}") content = requests.get(file['raw_url']).text all_code += f"File: {file['filename']}\n{content}\n\n" - if file in important_files: - important_files_content[file['filename']] = content - - # 전체 코드에 대한 리뷰 및 중요 파일에 대한 상세 리뷰 요청 - review_result = generate_review_prompt(all_code, important_files_content) - # 리뷰 결과 파싱 및 처리 - parsed_result = parse_review_result(review_result) - - # 전체 PR에 대한 코멘트 게시 - post_pr_comment(repo, pr_number, parsed_result['overall_review'], github_token) + # 전체 코드에 대한 간략한 리뷰 + overall_review = summarize_reviews(all_code) # 중요 파일에 대한 상세 리뷰 - for filename, file_review in parsed_result['file_reviews'].items(): - file_info = next(f for f in important_files if f['filename'] == filename) + detailed_reviews = [] + for file in important_files: + content = requests.get(file['raw_url']).text + review = review_code(content) + detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + + line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + line_comments = review_code(line_comments_prompt) + post_line_comments( - repo, - pr_number, - latest_commit_id, - filename, - file_info['patch'], - file_review['line_comments'], + repo, + pr_number, + latest_commit_id, + file['filename'], + file['patch'], + line_comments, github_token ) + + # 전체 요약 생성 + final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" + + post_pr_comment( + repo, + pr_number, + final_summary, + github_token + ) + else: logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 807ccea..171465d 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,13 +1,11 @@ import json + REVIEW_PROMPT_TEMPLATE = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: 전체 코드: {all_code} -중요 파일들: -{important_files} - 응답 형식: 1. 전체 리뷰: [여기에 전체 리뷰 내용] 2. 중요 파일 상세 리뷰: From 8449bdae54c7933948ddecd3e95bc309137aa3ab Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 01:11:59 +0900 Subject: [PATCH 22/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 113 ++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 31 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 1938ebe..0d82f5b 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -3,7 +3,7 @@ import requests import re import logging -from scripts.review_prompt import review_prompt +from scripts.review_prompt import generate_review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -179,6 +179,48 @@ def post_single_comment(line_num, comment_text, position): logger.info("모든 라인 코멘트 처리 완료") +def parse_and_post_review(repo, pr_number, commit_sha, review_result, token): + lines = review_result.split('\n') + overall_review = "" + current_file = "" + file_review = "" + line_comments = {} + + for line in lines: + if line.startswith("1. 전체 리뷰:"): + overall_review = line[len("1. 전체 리뷰:"):].strip() + elif line.startswith("2. 중요 파일 상세 리뷰:"): + continue + elif line.startswith(" ") and ": " in line: + filename, _ = line.strip().split(": ", 1) + current_file = filename + file_review = "" + line_comments[current_file] = {} + elif line.startswith(" - 전반적인 리뷰:"): + file_review = line[len(" - 전반적인 리뷰:"):].strip() + elif line.startswith(" - 라인별 코멘트:"): + continue + elif line.startswith(" ") and ": " in line: + line_num, comment = line.strip().split(": ", 1) + line_comments[current_file][int(line_num)] = comment + + # 전체 리뷰 게시 + post_pr_comment(repo, pr_number, f"전체 리뷰:\n{overall_review}", token) + + # 파일별 리뷰 및 라인 코멘트 게시 + for file, comments in line_comments.items(): + file_content = f"파일: {file}\n\n전반적인 리뷰:\n{file_review}\n\n라인별 코멘트:" + for line_num, comment in comments.items(): + file_content += f"\n{line_num}: {comment}" + + post_review_comment(repo, pr_number, commit_sha, file, 1, file_content, token) + + # 개별 라인 코멘트 게시 + for line_num, comment in comments.items(): + post_review_comment(repo, pr_number, commit_sha, file, line_num, comment, token) + + logger.info("모든 리뷰 코멘트가 성공적으로 게시되었습니다.") + def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -198,6 +240,7 @@ def main(): latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) all_code = "" + important_files_content = {} if pr_files: important_files = [f for f in pr_files if f['changes'] > 50] @@ -207,39 +250,47 @@ def main(): logger.info(f"파일 리뷰 중: {file['filename']}") content = requests.get(file['raw_url']).text all_code += f"File: {file['filename']}\n{content}\n\n" + if file in important_files: + important_files_content[file['filename']] = content - # 전체 코드에 대한 간략한 리뷰 - overall_review = summarize_reviews(all_code) - - # 중요 파일에 대한 상세 리뷰 - detailed_reviews = [] - for file in important_files: - content = requests.get(file['raw_url']).text - review = review_code(content) - detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - - line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" - line_comments = review_code(line_comments_prompt) - - post_line_comments( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['patch'], - line_comments, - github_token - ) + # 새로운 리뷰 프롬프트 생성 + review_prompt = generate_review_prompt(all_code, important_files_content) + + # 전체 코드에 대한 리뷰 + overall_review = review_code(review_prompt) + + # 리뷰 결과 파싱 및 코멘트 게시 + parse_and_post_review(repo, pr_number, latest_commit_id, overall_review, github_token) + + # # 중요 파일에 대한 상세 리뷰 + # detailed_reviews = [] + # for file in important_files: + # content = requests.get(file['raw_url']).text + # review = review_code(content) + # detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + + # line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + # line_comments = review_code(line_comments_prompt) + + # post_line_comments( + # repo, + # pr_number, + # latest_commit_id, + # file['filename'], + # file['patch'], + # line_comments, + # github_token + # ) # 전체 요약 생성 - final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" - - post_pr_comment( - repo, - pr_number, - final_summary, - github_token - ) + # final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" + + # post_pr_comment( + # repo, + # pr_number, + # final_summary, + # github_token + # ) else: logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") From 01567e3cba5d8bf8671a575812eed217e76ecf96 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 01:16:46 +0900 Subject: [PATCH 23/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 171465d..17a72ef 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,10 +1,7 @@ -import json - - -REVIEW_PROMPT_TEMPLATE = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: +review_prompt = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: 전체 코드: -{all_code} +{code} 응답 형식: 1. 전체 리뷰: [여기에 전체 리뷰 내용] @@ -19,7 +16,7 @@ """ def generate_review_prompt(all_code, important_files_content): - return REVIEW_PROMPT_TEMPLATE.format( - all_code=all_code, - important_files=json.dumps(important_files_content, indent=2) + return review_prompt.format( + code=all_code, + important_files="\n".join(f"{filename}:\n{content}" for filename, content in important_files_content.items()) ) \ No newline at end of file From 66dc26393a520a299e9c193ad44ce687061a6cdb Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 01:18:37 +0900 Subject: [PATCH 24/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 17a72ef..249f01e 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,7 +1,13 @@ -review_prompt = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: +import json + + +REVIEW_PROMPT_TEMPLATE = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: 전체 코드: -{code} +{all_code} + +중요 파일들: +{important_files} 응답 형식: 1. 전체 리뷰: [여기에 전체 리뷰 내용] @@ -16,7 +22,7 @@ """ def generate_review_prompt(all_code, important_files_content): - return review_prompt.format( - code=all_code, - important_files="\n".join(f"{filename}:\n{content}" for filename, content in important_files_content.items()) + return REVIEW_PROMPT_TEMPLATE.format( + all_code=all_code, + important_files=json.dumps(important_files_content, indent=2) ) \ No newline at end of file From 5cb4c13fab75fc460659874253633ebfa54fe262 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 01:21:58 +0900 Subject: [PATCH 25/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 0d82f5b..7083b6d 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -40,12 +40,12 @@ def get_latest_commit_id(repo, pr_number, token): pr_data = response.json() return pr_data['head']['sha'] -def review_code(pr_content): - prompt = review_prompt.format(code=pr_content) +def review_code(review_prompt): + # prompt = review_prompt.format(code=pr_content) url = 'http://localhost:11434/api/generate' data = { "model": "llama3.1", - "prompt": prompt, + "prompt": review_prompt, "stream": False, "options": { "temperature": 0.7, From aa39f64ac81fd281995194245157bebfe1619665 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 01:29:17 +0900 Subject: [PATCH 26/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 121 ++++++++++-------------------- scripts/review_prompt.py | 17 +---- 2 files changed, 43 insertions(+), 95 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 7083b6d..7cab672 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -3,7 +3,7 @@ import requests import re import logging -from scripts.review_prompt import generate_review_prompt +from scripts.review_prompt import review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -40,12 +40,12 @@ def get_latest_commit_id(repo, pr_number, token): pr_data = response.json() return pr_data['head']['sha'] -def review_code(review_prompt): - # prompt = review_prompt.format(code=pr_content) +def review_code(pr_content): + prompt = review_prompt.format(code=pr_content) url = 'http://localhost:11434/api/generate' data = { "model": "llama3.1", - "prompt": review_prompt, + "prompt": prompt, "stream": False, "options": { "temperature": 0.7, @@ -179,48 +179,6 @@ def post_single_comment(line_num, comment_text, position): logger.info("모든 라인 코멘트 처리 완료") -def parse_and_post_review(repo, pr_number, commit_sha, review_result, token): - lines = review_result.split('\n') - overall_review = "" - current_file = "" - file_review = "" - line_comments = {} - - for line in lines: - if line.startswith("1. 전체 리뷰:"): - overall_review = line[len("1. 전체 리뷰:"):].strip() - elif line.startswith("2. 중요 파일 상세 리뷰:"): - continue - elif line.startswith(" ") and ": " in line: - filename, _ = line.strip().split(": ", 1) - current_file = filename - file_review = "" - line_comments[current_file] = {} - elif line.startswith(" - 전반적인 리뷰:"): - file_review = line[len(" - 전반적인 리뷰:"):].strip() - elif line.startswith(" - 라인별 코멘트:"): - continue - elif line.startswith(" ") and ": " in line: - line_num, comment = line.strip().split(": ", 1) - line_comments[current_file][int(line_num)] = comment - - # 전체 리뷰 게시 - post_pr_comment(repo, pr_number, f"전체 리뷰:\n{overall_review}", token) - - # 파일별 리뷰 및 라인 코멘트 게시 - for file, comments in line_comments.items(): - file_content = f"파일: {file}\n\n전반적인 리뷰:\n{file_review}\n\n라인별 코멘트:" - for line_num, comment in comments.items(): - file_content += f"\n{line_num}: {comment}" - - post_review_comment(repo, pr_number, commit_sha, file, 1, file_content, token) - - # 개별 라인 코멘트 게시 - for line_num, comment in comments.items(): - post_review_comment(repo, pr_number, commit_sha, file, line_num, comment, token) - - logger.info("모든 리뷰 코멘트가 성공적으로 게시되었습니다.") - def main(): try: github_token = os.environ['GITHUB_TOKEN'] @@ -240,7 +198,6 @@ def main(): latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) all_code = "" - important_files_content = {} if pr_files: important_files = [f for f in pr_files if f['changes'] > 50] @@ -250,48 +207,50 @@ def main(): logger.info(f"파일 리뷰 중: {file['filename']}") content = requests.get(file['raw_url']).text all_code += f"File: {file['filename']}\n{content}\n\n" - if file in important_files: - important_files_content[file['filename']] = content - - # 새로운 리뷰 프롬프트 생성 - review_prompt = generate_review_prompt(all_code, important_files_content) - # 전체 코드에 대한 리뷰 - overall_review = review_code(review_prompt) - - # 리뷰 결과 파싱 및 코멘트 게시 - parse_and_post_review(repo, pr_number, latest_commit_id, overall_review, github_token) - - # # 중요 파일에 대한 상세 리뷰 - # detailed_reviews = [] - # for file in important_files: - # content = requests.get(file['raw_url']).text - # review = review_code(content) - # detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - - # line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" - # line_comments = review_code(line_comments_prompt) - - # post_line_comments( - # repo, - # pr_number, - # latest_commit_id, - # file['filename'], - # file['patch'], - # line_comments, - # github_token - # ) + # 전체 코드에 대한 간략한 리뷰 + overall_review = summarize_reviews(all_code) + + # 중요 파일에 대한 상세 리뷰 + detailed_reviews = [] + for file in important_files: + content = requests.get(file['raw_url']).text + review = review_code(content) + detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + + line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + line_comments = review_code(line_comments_prompt) + + post_line_comments( + repo, + pr_number, + latest_commit_id, + file['filename'], + file['patch'], + line_comments, + github_token + ) # 전체 요약 생성 - # final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" - - # post_pr_comment( + final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" + + # post_review_comment( # repo, # pr_number, - # final_summary, + # latest_commit_id, + # file['filename'], + # file['changes'], + # f"AI Code Review:\n\n{review}", # github_token # ) + post_pr_comment( + repo, + pr_number, + final_summary, + github_token + ) + else: logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 249f01e..b8795ed 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,14 +1,9 @@ -import json - - -REVIEW_PROMPT_TEMPLATE = """전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: +review_prompt = """ +전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: 전체 코드: {all_code} -중요 파일들: -{important_files} - 응답 형식: 1. 전체 리뷰: [여기에 전체 리뷰 내용] 2. 중요 파일 상세 리뷰: @@ -19,10 +14,4 @@ ... [파일명2]: ... -""" - -def generate_review_prompt(all_code, important_files_content): - return REVIEW_PROMPT_TEMPLATE.format( - all_code=all_code, - important_files=json.dumps(important_files_content, indent=2) - ) \ No newline at end of file +""" \ No newline at end of file From 1b820910e73e5f016e662fb4c6c305eeeb490e7a Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 02:07:58 +0900 Subject: [PATCH 27/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 136 +++++++++++++++++------------- 1 file changed, 78 insertions(+), 58 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 7cab672..e903354 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -179,80 +179,100 @@ def post_single_comment(line_num, comment_text, position): logger.info("모든 라인 코멘트 처리 완료") -def main(): +def get_environment_variables(): try: github_token = os.environ['GITHUB_TOKEN'] repo = os.environ['GITHUB_REPOSITORY'] event_path = os.environ['GITHUB_EVENT_PATH'] - - logger.info(f"저장소 리뷰 시작: {repo}") - logger.debug(f"GitHub 토큰 (처음 5자): {github_token[:5]}...") + return github_token, repo, event_path + except KeyError as e: + logger.error(f"환경 변수가 설정되지 않음: {str(e)}") + raise - with open(event_path) as f: - event = json.load(f) +def fetch_pr_data(repo, pr_number, github_token): + pr_files = get_pr_files(repo, pr_number, github_token) + if not pr_files: + logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") + return None, None + latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) + return pr_files, latest_commit_id - pr_number = event['pull_request']['number'] - logger.info(f"PR 번호 리뷰 중: {pr_number}") - - pr_files = get_pr_files(repo, pr_number, github_token) - latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) +def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): + all_code = "" + important_files = [f for f in pr_files if f['changes'] > 50] + for file in pr_files: + if file['status'] != 'removed': + logger.info(f"파일 리뷰 중: {file['filename']}") + content = requests.get(file['raw_url']).text + all_code += f"File: {file['filename']}\n{content}\n\n" - all_code = "" + # 전체 코드에 대한 간략한 리뷰 + overall_review = summarize_reviews(all_code) - if pr_files: - important_files = [f for f in pr_files if f['changes'] > 50] + # 중요 파일에 대한 상세 리뷰 + detailed_reviews = [] + for file in important_files: + content = requests.get(file['raw_url']).text + review = review_code(content) + detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - for file in pr_files: - if file['status'] != 'removed': - logger.info(f"파일 리뷰 중: {file['filename']}") - content = requests.get(file['raw_url']).text - all_code += f"File: {file['filename']}\n{content}\n\n" + line_comments_prompt = ( + f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " + f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + ) + line_comments = review_code(line_comments_prompt) + + post_line_comments( + repo, + pr_number, + latest_commit_id, + file['filename'], + file['patch'], + line_comments, + github_token + ) + + return overall_review, detailed_reviews - # 전체 코드에 대한 간략한 리뷰 - overall_review = summarize_reviews(all_code) +def create_review_summary(overall_review, detailed_reviews): + return f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" - # 중요 파일에 대한 상세 리뷰 - detailed_reviews = [] - for file in important_files: - content = requests.get(file['raw_url']).text - review = review_code(content) - detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") +def main(): + try: + github_token, repo, event_path = get_environment_variables() + + logger.info(f"저장소 리뷰 시작: {repo}") + logger.debug(f"GitHub 토큰 (처음 5자): {github_token[:5]}...") - line_comments_prompt = f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. 형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" - line_comments = review_code(line_comments_prompt) + with open(event_path) as f: + event = json.load(f) - post_line_comments( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['patch'], - line_comments, - github_token - ) + pr_number = event.get('pull_request', {}).get('number') + if pr_number is None: + logger.error("PR 번호를 찾을 수 없습니다. GitHub 이벤트 파일이 pull_request 이벤트를 포함하고 있는지 확인하세요.") - # 전체 요약 생성 - final_summary = f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" - - # post_review_comment( - # repo, - # pr_number, - # latest_commit_id, - # file['filename'], - # file['changes'], - # f"AI Code Review:\n\n{review}", - # github_token - # ) + logger.info(f"PR 번호 {pr_number} 리뷰 시작합니다.") + + pr_files, latest_commit_id = fetch_pr_data(repo, pr_number, github_token) + if not pr_files: + return + + overall_review, detailed_reviews = generate_reviews( + pr_files, + repo, + pr_number, + latest_commit_id, + github_token + ) - post_pr_comment( - repo, - pr_number, - final_summary, - github_token - ) + final_summary = create_review_summary(overall_review, detailed_reviews) - else: - logger.warning("파일을 찾을 수 없거나 PR 파일을 가져오는 데 실패했습니다.") + post_pr_comment( + repo, + pr_number, + final_summary, + github_token + ) except KeyError as e: logger.error(f"환경 변수가 설정되지 않음: {str(e)}") From 836b65a4cdbd722412443f69bfc3bb5edd582c50 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 02:14:17 +0900 Subject: [PATCH 28/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 43 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index e903354..97d4030 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -206,31 +206,38 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): content = requests.get(file['raw_url']).text all_code += f"File: {file['filename']}\n{content}\n\n" + if not all_code: + logger.warning("리뷰할 코드가 없습니다. 모든 파일이 삭제되었거나 내용을 가져오는 데 실패했습니다.") + return None, [] + # 전체 코드에 대한 간략한 리뷰 overall_review = summarize_reviews(all_code) # 중요 파일에 대한 상세 리뷰 detailed_reviews = [] for file in important_files: - content = requests.get(file['raw_url']).text - review = review_code(content) - detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - - line_comments_prompt = ( - f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " - f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" - ) - line_comments = review_code(line_comments_prompt) + try: + content = requests.get(file['raw_url']).text + review = review_code(content) + detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - post_line_comments( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['patch'], - line_comments, - github_token - ) + line_comments_prompt = ( + f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " + f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + ) + line_comments = review_code(line_comments_prompt) + post_line_comments( + repo, + pr_number, + latest_commit_id, + file['filename'], + file['patch'], + line_comments, + github_token + ) + except requests.RequestException as e: + logger.error(f"중요 파일 내용을 가져오는 중 오류 발생: {str(e)}") + continue return overall_review, detailed_reviews From 93885c3f8d56debd382fabeb96b5409f1c13e72b Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 02:31:24 +0900 Subject: [PATCH 29/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 41 ++++++++++++++----------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 97d4030..dafe64f 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -41,7 +41,7 @@ def get_latest_commit_id(repo, pr_number, token): return pr_data['head']['sha'] def review_code(pr_content): - prompt = review_prompt.format(code=pr_content) + prompt = review_prompt.format(all_code=pr_content) url = 'http://localhost:11434/api/generate' data = { "model": "llama3.1", @@ -216,28 +216,25 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): # 중요 파일에 대한 상세 리뷰 detailed_reviews = [] for file in important_files: - try: - content = requests.get(file['raw_url']).text - review = review_code(content) - detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") + content = requests.get(file['raw_url']).text + review = review_code(content) + detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - line_comments_prompt = ( - f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " - f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" - ) - line_comments = review_code(line_comments_prompt) - post_line_comments( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['patch'], - line_comments, - github_token - ) - except requests.RequestException as e: - logger.error(f"중요 파일 내용을 가져오는 중 오류 발생: {str(e)}") - continue + line_comments_prompt = ( + f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " + f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + ) + line_comments = review_code(line_comments_prompt) + + post_line_comments( + repo, + pr_number, + latest_commit_id, + file['filename'], + file['patch'], + line_comments, + github_token + ) return overall_review, detailed_reviews From 1ae125e83cf9db4190ef7569073f64fd2331e6a6 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 03:28:35 +0900 Subject: [PATCH 30/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Groq API 적용 --- .github/scripts/ai_code_review.py | 32 ++++++++++++++--- .github/workflows/code-review.yml | 53 +++++++++++++++++++---------- app/backend/requirements.txt | 1 + app/backend/src/main/core/config.py | 2 +- 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index dafe64f..723cb77 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -2,12 +2,19 @@ import os import requests import re +import groq import logging + +from dotenv import load_dotenv from scripts.review_prompt import review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) +load_dotenv('app/backend/.env') + +groq_client = groq.Groq(api_key=os.environ["GROQ_API_KEY"]) + def get_pr_files(repo, pr_number, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" headers = { @@ -40,7 +47,24 @@ def get_latest_commit_id(repo, pr_number, token): pr_data = response.json() return pr_data['head']['sha'] -def review_code(pr_content): +def review_code_groq(pr_content): + prompt = review_prompt.format(all_code=pr_content) + try: + response = groq_client.chat.completions.create( + model="llama-3.1-70b-versatile", + messages=[ + {"role": "system", "content": "You are an expert code reviewer."}, + {"role": "user", "content": prompt} + ], + temperature=0.7, + max_tokens=1024 + ) + return response.choices[0].message.content + except Exception as e: + logger.error(f"Groq API 호출 중 오류 발생: {str(e)}") + return f"코드 리뷰 중 발생한 에러: {str(e)}" + +def review_code_ollama(pr_content): prompt = review_prompt.format(all_code=pr_content) url = 'http://localhost:11434/api/generate' data = { @@ -95,7 +119,7 @@ def post_review_comment(repo, pr_number, commit_sha, path, position, body, token def summarize_reviews(all_reviews): summary_prompt = f"다음은 전체적인 코드 리뷰 결과입니다 : \n\n{''.join(all_reviews)}" - summary = review_code(summary_prompt) + summary = review_code_groq(summary_prompt) return summary def post_pr_comment(repo, pr_number, body, token): @@ -217,14 +241,14 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): detailed_reviews = [] for file in important_files: content = requests.get(file['raw_url']).text - review = review_code(content) + review = review_code_groq(content) detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") line_comments_prompt = ( f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" ) - line_comments = review_code(line_comments_prompt) + line_comments = review_code_groq(line_comments_prompt) post_line_comments( repo, diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index a446bd4..cd0d48d 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -10,33 +10,50 @@ permissions: jobs: code-review: - runs-on: self-hosted + runs-on: ubuntu-latest + # runs-on: self-hosted steps: - uses: actions/checkout@v4 - - name: Set Python Path - run: echo "PYTHON_PATH=$(which python3)" >> $GITHUB_ENV + # - name: Set Python Path + # run: echo "PYTHON_PATH=$(which python3)" >> $GITHUB_ENV + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' - - name: Install dependencies - run: | - ${{ env.PYTHON_PATH }} -m pip install --upgrade pip - ${{ env.PYTHON_PATH }} -m pip install requests + # - name: Install dependencies + # run: | + # ${{ env.PYTHON_PATH }} -m pip install --upgrade pip + # ${{ env.PYTHON_PATH }} -m pip install requests - - name: Check Ollama availability - run: | - curl http://localhost:11434/api/tags - - - name: Check Python version + - name: Install dependencies run: | - python3 --version - which python3 + python -m pip install --upgrade pip + pip install requests groq - name: Run AI Code Review env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} run: | - echo "Starting AI Code Review" - export PYTHONPATH=$PYTHONPATH:${{ github.workspace }} - /usr/local/bin/python3 /Users/jonghyunjung/VisualStudioProjects/neonadeuli-main/.github/scripts/ai_code_review.py - echo "AI Code Review completed" \ No newline at end of file + python .github/scripts/ai_code_review.py + + # - name: Check Ollama availability + # run: | + # curl http://localhost:11434/api/tags + + # - name: Check Python version + # run: | + # python3 --version + # which python3 + + # - name: Run AI Code Review + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # run: | + # echo "Starting AI Code Review" + # export PYTHONPATH=$PYTHONPATH:${{ github.workspace }} + # /usr/local/bin/python3 /Users/jonghyunjung/VisualStudioProjects/neonadeuli-main/.github/scripts/ai_code_review.py + # echo "AI Code Review completed" \ No newline at end of file diff --git a/app/backend/requirements.txt b/app/backend/requirements.txt index 309fd58..ad8ace1 100644 --- a/app/backend/requirements.txt +++ b/app/backend/requirements.txt @@ -25,3 +25,4 @@ flake8-comprehensions flake8-pytest-style isort mypy +groq \ No newline at end of file diff --git a/app/backend/src/main/core/config.py b/app/backend/src/main/core/config.py index 971f5b3..994a2fb 100644 --- a/app/backend/src/main/core/config.py +++ b/app/backend/src/main/core/config.py @@ -2,7 +2,7 @@ from dotenv import load_dotenv # load .env file -load_dotenv() +load_dotenv('app/backend/.env') from pydantic import ( PostgresDsn, From 1161f1e01b73cb64c5529793f31ef43075de427f Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 03:37:49 +0900 Subject: [PATCH 31/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20Groq=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Groq 환경변수 추가 --- .github/scripts/ai_code_review.py | 6 ++---- app/backend/src/main/core/config.py | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 723cb77..6b9cdd8 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -5,15 +5,13 @@ import groq import logging -from dotenv import load_dotenv +from app.backend.src.main.core.config import settings from scripts.review_prompt import review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) -load_dotenv('app/backend/.env') - -groq_client = groq.Groq(api_key=os.environ["GROQ_API_KEY"]) +groq_client = groq.Groq(api_key=settings.GROQ_API_KEY) def get_pr_files(repo, pr_number, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" diff --git a/app/backend/src/main/core/config.py b/app/backend/src/main/core/config.py index 994a2fb..0d80657 100644 --- a/app/backend/src/main/core/config.py +++ b/app/backend/src/main/core/config.py @@ -73,6 +73,9 @@ class Settings(BaseSettings): # ALGORITHM : str # ACCESS_TOKEN_EXPIRE_MINUTES : int + # Groq API + GROQ_API_KEY: str + # 기본 이미지 URL # DEFAULT_IMAGE_URL : str From 9240aabb25e841cd4b26cfc62204739a3f797f55 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 03:42:42 +0900 Subject: [PATCH 32/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20Groq=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 6b9cdd8..0fe6c64 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -5,13 +5,12 @@ import groq import logging -from app.backend.src.main.core.config import settings from scripts.review_prompt import review_prompt logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) -groq_client = groq.Groq(api_key=settings.GROQ_API_KEY) +groq_client = groq.Groq(api_key=os.environ["GROQ_API_KEY"]) def get_pr_files(repo, pr_number, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" From 86fbd46eb59545ec234c103f0f046087f3f795ad Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 03:47:32 +0900 Subject: [PATCH 33/74] =?UTF-8?q?fix(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20Groq=20=ED=99=98=EA=B2=BD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EA=B2=BD=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/code-review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index cd0d48d..acc99f7 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -38,6 +38,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} run: | + export PYTHONPATH=$PYTHONPATH:${{ github.workspace }} python .github/scripts/ai_code_review.py # - name: Check Ollama availability From df063d8868d2f2d43bf6f2bfa2582f7631cffc57 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 04:54:51 +0900 Subject: [PATCH 34/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index b8795ed..a655ba5 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,17 +1,21 @@ review_prompt = """ -전체 코드에 대한 간략한 리뷰를 제공하고, 다음 중요 파일들에 대해 상세한 리뷰와 라인별 코멘트를 제공해주세요: +당신은 전문적인 코드 리뷰어입니다. 주어진 코드를 분석하고 다음 형식으로 리뷰를 제공해주세요: + +안녕하세요! 리뷰봇입니다. + +1. **좋은 점**: + * [좋은 점 나열] + +2. **개선할 점**: + * [개선이 필요한 점 나열] + +3. **제안 사항**: + * [구체적인 개선 제안, 코드 예시 포함] + +수고하셨습니다! 코드 리뷰를 통해 개선할 수 있는 부분이 있으니, 이를 참고하여 더욱 나은 코드로 발전시켜 주시기 바랍니다.👍 전체 코드: {all_code} -응답 형식: -1. 전체 리뷰: [여기에 전체 리뷰 내용] -2. 중요 파일 상세 리뷰: - [파일명1]: - - 전반적인 리뷰: [리뷰 내용] - - 라인별 코멘트: - [라인 번호]: [코멘트] - ... - [파일명2]: - ... +응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. """ \ No newline at end of file From 92e8bf17487ae21147461b41564c78ea34dc08cf Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 08:10:52 +0900 Subject: [PATCH 35/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 개별 코멘트 파일 전체 코멘트와 별도 생성 - 중요 파일 선정 기준 변경 (파일 크기와 변경 비율) --- .github/scripts/ai_code_review.py | 85 ++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 0fe6c64..cf19e4b 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -5,7 +5,12 @@ import groq import logging -from scripts.review_prompt import review_prompt +from scripts.review_prompt import ( + get_review_prompt, + get_file_review_prompt, + get_line_comments_prompt, + get_total_comments_prompt +) logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -45,7 +50,7 @@ def get_latest_commit_id(repo, pr_number, token): return pr_data['head']['sha'] def review_code_groq(pr_content): - prompt = review_prompt.format(all_code=pr_content) + prompt = get_review_prompt(pr_content) try: response = groq_client.chat.completions.create( model="llama-3.1-70b-versatile", @@ -62,7 +67,7 @@ def review_code_groq(pr_content): return f"코드 리뷰 중 발생한 에러: {str(e)}" def review_code_ollama(pr_content): - prompt = review_prompt.format(all_code=pr_content) + prompt = get_review_prompt(pr_content) url = 'http://localhost:11434/api/generate' data = { "model": "llama3.1", @@ -218,9 +223,14 @@ def fetch_pr_data(repo, pr_number, github_token): latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) return pr_files, latest_commit_id +def is_important_file(file): + total_lines = file.get('additions', 0) + file.get('deletions', 0) + change_ratio = total_lines / file.get('changes', 1) + return file['changes'] > 50 or change_ratio > 0.3 + def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): all_code = "" - important_files = [f for f in pr_files if f['changes'] > 50] + important_files = [f for f in pr_files if is_important_file(f)] for file in pr_files: if file['status'] != 'removed': logger.info(f"파일 리뷰 중: {file['filename']}") @@ -232,19 +242,27 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): return None, [] # 전체 코드에 대한 간략한 리뷰 - overall_review = summarize_reviews(all_code) + review_prompt = get_review_prompt(all_code) + overall_review = review_code_groq(review_prompt) # 중요 파일에 대한 상세 리뷰 - detailed_reviews = [] for file in important_files: content = requests.get(file['raw_url']).text - review = review_code_groq(content) - detailed_reviews.append(f"File: {file['filename']}\n{review}\n\n") - - line_comments_prompt = ( - f"다음 {file['filename']} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. " - f"형식은 '라인 번호: 코멘트'로 해주세요.\n\n{content}" + file_review_prompt = get_file_review_prompt(file['filename'], content) + file_review = review_code_groq(file_review_prompt) + + # 파일 전체에 대한 리뷰 코멘트 + post_file_comment( + repo, + pr_number, + latest_commit_id, + file['filename'], + file_review, + github_token ) + + # 라인 별 코멘트 + line_comments_prompt = get_line_comments_prompt(file['filename'], content) line_comments = review_code_groq(line_comments_prompt) post_line_comments( @@ -257,10 +275,29 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): github_token ) - return overall_review, detailed_reviews + return overall_review -def create_review_summary(overall_review, detailed_reviews): - return f"Overall Review:\n{overall_review}\n\nDetailed Reviews:\n{''.join(detailed_reviews)}" +def post_file_comment(repo, pr_number, commit_sha, file_path, body, token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + data = { + "body": body, + "commit_id": commit_sha, + "path": file_path, + "position": 1 + } + + try: + response = requests.post(url, headers=headers, json=data) + response.raise_for_status() + logger.info("PR 파일 코멘트가 성공적으로 게시되었습니다.") + except requests.RequestException as e: + logger.error(f"PR 코멘트 게시 중 오류 발생: {str(e)}") + logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") def main(): try: @@ -282,7 +319,7 @@ def main(): if not pr_files: return - overall_review, detailed_reviews = generate_reviews( + overall_review = generate_reviews( pr_files, repo, pr_number, @@ -290,14 +327,14 @@ def main(): github_token ) - final_summary = create_review_summary(overall_review, detailed_reviews) - - post_pr_comment( - repo, - pr_number, - final_summary, - github_token - ) + if overall_review: + comment = get_total_comments_prompt(overall_review) + post_pr_comment( + repo, + pr_number, + comment, + github_token + ) except KeyError as e: logger.error(f"환경 변수가 설정되지 않음: {str(e)}") From afe21bd78bda48e5d77c26e7be64f5a9a5da0752 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 08:11:02 +0900 Subject: [PATCH 36/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 69 +++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index a655ba5..4f15f90 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,21 +1,66 @@ -review_prompt = """ +REVIEW_PROMPT = """ 당신은 전문적인 코드 리뷰어입니다. 주어진 코드를 분석하고 다음 형식으로 리뷰를 제공해주세요: -안녕하세요! 리뷰봇입니다. +## 전체 코드 리뷰 -1. **좋은 점**: - * [좋은 점 나열] +### 좋은 점 +[좋은 점 나열] -2. **개선할 점**: - * [개선이 필요한 점 나열] +### 개선할 점 +[개선이 필요한 점 나열] -3. **제안 사항**: - * [구체적인 개선 제안, 코드 예시 포함] - -수고하셨습니다! 코드 리뷰를 통해 개선할 수 있는 부분이 있으니, 이를 참고하여 더욱 나은 코드로 발전시켜 주시기 바랍니다.👍 +### 제안 사항 +[구체적인 개선 제안, 코드 예시 포함] 전체 코드: -{all_code} +{code} 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. -""" \ No newline at end of file +""" + +FILE_REVIEW_PROMPT = """ +다음 {filename} 파일의 코드를 리뷰하고, 아래 형식으로 상세한 리뷰를 제공해주세요: + +## {filename} 파일 리뷰 + +### 주요 기능 +[파일의 주요 기능 설명] + +### 좋은 점 +[좋은 점 나열] + +### 개선할 점 +[개선이 필요한 점 나열] + +### 제안 사항 +[구체적인 개선 제안, 코드 예시 포함] + +파일 내용: +{content} +""" + +LINE_COMMENTS_PROMPT = """ +다음 {filename} 파일의 코드를 리뷰하고, 중요한 라인에 대해 구체적인 코멘트를 제공해주세요. +형식은 '라인 번호: 코멘트'로 해주세요. + +{content} +""" + +OVERALL_COMMENTS_PROMPT = """ +## AI 코드 리뷰 요약 + +{overall_review} +""" + +def get_review_prompt(code): + return REVIEW_PROMPT.format(code=code) + +def get_file_review_prompt(filename, content): + return FILE_REVIEW_PROMPT.format(filename=filename, content=content) + +def get_line_comments_prompt(filename, content): + return LINE_COMMENTS_PROMPT.format(filename=filename, content=content) + +def get_total_comments_prompt(overall_review): + return OVERALL_COMMENTS_PROMPT.format(overall_review=overall_review) + \ No newline at end of file From 5ba5e2adf559da984d4005f60b67030e73bdb4e6 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 19:27:22 +0900 Subject: [PATCH 37/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 삭제 파일도 전체 리뷰에 언급될 수 있도록 구현 - 중요 파일 선정 조건 변경 - 리뷰 대상 제외 파일 조건 추가 --- .github/scripts/ai_code_review.py | 47 ++++++++++++++++--- .github/scripts/review-test/data_processor.py | 12 ----- .github/scripts/review-test/main.py | 12 ----- .github/scripts/review-test/test_utils.py | 16 ------- .github/scripts/review-test/utils.py | 18 ------- 5 files changed, 41 insertions(+), 64 deletions(-) delete mode 100644 .github/scripts/review-test/data_processor.py delete mode 100644 .github/scripts/review-test/main.py delete mode 100644 .github/scripts/review-test/test_utils.py delete mode 100644 .github/scripts/review-test/utils.py diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index cf19e4b..6672c7c 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -4,6 +4,12 @@ import re import groq import logging +from review_config import ( + IGNORED_EXTENSIONS, + IGNORED_FILES, + IMPORTANT_FILE_CHANGE_THRESHOLD, + IMPORTANT_FILE_CHANGE_RATIO +) from scripts.review_prompt import ( get_review_prompt, @@ -224,21 +230,46 @@ def fetch_pr_data(repo, pr_number, github_token): return pr_files, latest_commit_id def is_important_file(file): + filename = file['filename'] + if filename in IGNORED_FILES: + logger.debug(f"무시된 파일: {filename}") + return False + + if any(filename.endswith(ext) for ext in IGNORED_EXTENSIONS): + logger.debug(f"무시할 확장자 파일: {filename}") + return False + + if file['status'] == 'removed': + logger.info(f"삭제된 파일: {file['filename']}") + return True + total_lines = file.get('additions', 0) + file.get('deletions', 0) change_ratio = total_lines / file.get('changes', 1) - return file['changes'] > 50 or change_ratio > 0.3 + is_important = file['changes'] > IMPORTANT_FILE_CHANGE_THRESHOLD or change_ratio > IMPORTANT_FILE_CHANGE_RATIO + + if is_important: + logger.info(f"중요 파일로 선정: {file['filename']} (변경: {file['changes']}줄, 비율: {change_ratio:.2f})") + else: + logger.debug(f"일반 파일: {file['filename']} (변경: {file['changes']}줄, 비율: {change_ratio:.2f})") + + return is_important def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): all_code = "" important_files = [f for f in pr_files if is_important_file(f)] + + logger.info(f"총 {len(pr_files)}개 파일 중 {len(important_files)}개 파일이 중요 파일로 선정되었습니다.") + for file in pr_files: - if file['status'] != 'removed': + if file['status'] == 'removed': + all_code += f"File: {file['filename']} (DELETED)\n\n" + else: logger.info(f"파일 리뷰 중: {file['filename']}") content = requests.get(file['raw_url']).text all_code += f"File: {file['filename']}\n{content}\n\n" if not all_code: - logger.warning("리뷰할 코드가 없습니다. 모든 파일이 삭제되었거나 내용을 가져오는 데 실패했습니다.") + logger.warning("리뷰할 코드가 없습니다. 모든 파일 내용을 가져오는 데 실패했습니다.") return None, [] # 전체 코드에 대한 간략한 리뷰 @@ -247,9 +278,13 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): # 중요 파일에 대한 상세 리뷰 for file in important_files: - content = requests.get(file['raw_url']).text - file_review_prompt = get_file_review_prompt(file['filename'], content) - file_review = review_code_groq(file_review_prompt) + logger.info(f"중요 파일 상세 리뷰 중: {file['filename']}") + if file['status'] == 'removed': + file_review = f"파일 '{file['filename']}'이(가) 삭제되었습니다. 이 변경이 적절한지 확인해 주세요." + else: + content = requests.get(file['raw_url']).text + file_review_prompt = get_file_review_prompt(file['filename'], content) + file_review = review_code_groq(file_review_prompt) # 파일 전체에 대한 리뷰 코멘트 post_file_comment( diff --git a/.github/scripts/review-test/data_processor.py b/.github/scripts/review-test/data_processor.py deleted file mode 100644 index 1cd522c..0000000 --- a/.github/scripts/review-test/data_processor.py +++ /dev/null @@ -1,12 +0,0 @@ -def process_data(data): - processed = [] - for i in range(len(data)): - processed.append(data[i] * 2) - return processed - -def filter_data(data, threshold): - filtered = [] - for item in data: - if item > threshold: - filtered.append(item) - return filtered \ No newline at end of file diff --git a/.github/scripts/review-test/main.py b/.github/scripts/review-test/main.py deleted file mode 100644 index 455604f..0000000 --- a/.github/scripts/review-test/main.py +++ /dev/null @@ -1,12 +0,0 @@ -from data_processor import process_data -from utils import calculate_average, format_output - -def main(): - data = [1, 2, 3, 4, 5] - processed_data = process_data(data) - average = calculate_average(processed_data) - formatted_output = format_output(average) - print(formatted_output) - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/.github/scripts/review-test/test_utils.py b/.github/scripts/review-test/test_utils.py deleted file mode 100644 index eb2d9da..0000000 --- a/.github/scripts/review-test/test_utils.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest -from utils import calculate_average, is_prime - -class TestUtils(unittest.TestCase): - def test_calculate_average(self): - self.assertEqual(calculate_average([1, 2, 3, 4, 5]), 3) - self.assertEqual(calculate_average([]), 0) - - def test_is_prime(self): - self.assertTrue(is_prime(2)) - self.assertTrue(is_prime(17)) - self.assertFalse(is_prime(4)) - self.assertFalse(is_prime(1)) - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/.github/scripts/review-test/utils.py b/.github/scripts/review-test/utils.py deleted file mode 100644 index 821b974..0000000 --- a/.github/scripts/review-test/utils.py +++ /dev/null @@ -1,18 +0,0 @@ -def calculate_average(numbers): - total = 0 - count = 0 - for num in numbers: - total += num - count += 1 - return total / count if count > 0 else 0 - -def format_output(value): - return f"The result is: {value:.2f}" - -def is_prime(n): - if n < 2: - return False - for i in range(2, n): - if n % i == 0: - return False - return True \ No newline at end of file From 23ebf36464c76dd1152548b923bb1c7d69d16aff Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 19:28:29 +0900 Subject: [PATCH 38/74] =?UTF-8?q?feat(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=ED=99=98=EA=B2=BD=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/review_config.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/scripts/review_config.py diff --git a/.github/scripts/review_config.py b/.github/scripts/review_config.py new file mode 100644 index 0000000..2766702 --- /dev/null +++ b/.github/scripts/review_config.py @@ -0,0 +1,25 @@ +# 리뷰에서 제외할 파일 목록 +IGNORED_FILES = [ + '.gitignore', + 'requirements.txt', + 'docker-compose.yml', + 'Dockerfile', + 'setup.cfg', + 'pyproject.toml', + '.env.example', + 'README.md', + 'LICENSE', +] + +# 리뷰에서 제외할 파일 확장자 +IGNORED_EXTENSIONS = [ + '.md', + '.txt', + '.log', + '.json', + '.yaml', '.yml', +] + +# 중요 파일 판단 기준 +IMPORTANT_FILE_CHANGE_THRESHOLD = 100 +IMPORTANT_FILE_CHANGE_RATIO = 0.5 \ No newline at end of file From fbe3f2369169a9b61e60a67559a399a81474bd4a Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 22:37:10 +0900 Subject: [PATCH 39/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 개별 코멘트 중요도 평가 로직 추가 - 파일 당 최대 코멘트 수 3개 설정 --- .github/scripts/ai_code_review.py | 83 +++++++++++++++++++++++++------ .github/scripts/review_config.py | 5 +- 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 6672c7c..d7e94c0 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -1,5 +1,6 @@ import json import os +from typing import List, Tuple import requests import re import groq @@ -8,7 +9,8 @@ IGNORED_EXTENSIONS, IGNORED_FILES, IMPORTANT_FILE_CHANGE_THRESHOLD, - IMPORTANT_FILE_CHANGE_RATIO + IMPORTANT_FILE_CHANGE_RATIO, + MAX_COMMENTS_PER_FILE ) from scripts.review_prompt import ( @@ -190,24 +192,75 @@ def post_single_comment(line_num, comment_text, position): logger.error(f"응답 헤더: {e.response.headers if 'response' in locals() else '알 수 없음'}") logger.error(f"응답 내용: {e.response.text if 'response' in locals() else '알 수 없음'}") + def parse_comments(line_comments: str) -> List[Tuple[int, str]]: + parsed_comments = [] + for comment in line_comments.split('\n'): + match = re.match(r'(\d+):\s*(.*)', comment) + if match: + line_num, comment_text = match.groups() + try: + line_num = int(line_num) + parsed_comments.append((line_num, comment_text)) + except ValueError: + logger.warning(f"잘못된 라인 번호 형식: {line_num}") + else: + logger.warning(f"파싱할 수 없는 코멘트 형식: {comment}") + return parsed_comments + + def evaluate_importance(comment: str) -> int: + # 여기에 코멘트의 중요도를 평가하는 로직을 구현합니다. + # 예를 들어, 특정 키워드의 존재 여부, 코멘트의 길이 등을 고려할 수 있습니다. + importance = 0 + if "중요" in comment or "critical" in comment.lower(): + importance += 5 + if "버그" in comment or "bug" in comment.lower(): + importance += 4 + if "개선" in comment or "improvement" in comment.lower(): + importance += 3 + importance += len(comment) // 50 # 긴 코멘트에 약간의 가중치 부여 + return importance + line_numbers = get_line_numbers(patch) + parsed_comments = parse_comments(line_comments) + # 중요도에 따라 코멘트 정렬 + sorted_comments = sorted(parsed_comments, key=lambda x: evaluate_importance(x[1]), reverse=True) + + comments_posted = 0 # 라인 코멘트 파싱 및 게시 - for comment in line_comments.split('\n'): - match = re.match(r'(\d+):\s*(.*)', comment) - if match: - line_num, comment_text = match.groups() - try: - line_num = int(line_num) - if 0 <= line_num - 1 < len(line_numbers): - position = line_numbers[line_num - 1] - post_single_comment(line_num, comment_text, position) - else: - logger.warning(f"라인 {line_num}이 유효한 범위를 벗어났습니다.") - except ValueError: - logger.warning(f"잘못된 라인 번호 형식: {line_num}") + for line_num, comment_text in sorted_comments[:MAX_COMMENTS_PER_FILE]: + if 0 <= line_num - 1 < len(line_numbers): + position = line_numbers[line_num - 1] + if post_single_comment(line_num, comment_text, position): + comments_posted += 1 else: - logger.warning(f"파싱할 수 없는 코멘트 형식: {comment}") + logger.warning(f"라인 {line_num}이 유효한 범위를 벗어났습니다.") + + # for comment in line_comments.split('\n'): + # if comments_posted >= MAX_COMMENTS_PER_FILE: + # logger.info(f"{filename}: 최대 코멘트 수({MAX_COMMENTS_PER_FILE})에 도달했습니다. 나머지 코멘트는 생략됩니다.") + # break + + # match = re.match(r'(\d+):\s*(.*)', comment) + # if match: + # line_num, comment_text = match.groups() + # try: + # line_num = int(line_num) + # if 0 <= line_num - 1 < len(line_numbers): + # position = line_numbers[line_num - 1] + # if post_single_comment(line_num, comment_text, position): + # comments_posted += 1 + # else: + # logger.warning(f"라인 {line_num}이 유효한 범위를 벗어났습니다.") + # except ValueError: + # logger.warning(f"잘못된 라인 번호 형식: {line_num}") + # else: + # logger.warning(f"파싱할 수 없는 코멘트 형식: {comment}") + + if comments_posted == 0: + logger.info(f"{filename}: 추가된 코멘트가 없습니다.") + else: + logger.info(f"{filename}: 총 {comments_posted}개의 코멘트가 추가되었습니다.") logger.info("모든 라인 코멘트 처리 완료") diff --git a/.github/scripts/review_config.py b/.github/scripts/review_config.py index 2766702..39cfae0 100644 --- a/.github/scripts/review_config.py +++ b/.github/scripts/review_config.py @@ -22,4 +22,7 @@ # 중요 파일 판단 기준 IMPORTANT_FILE_CHANGE_THRESHOLD = 100 -IMPORTANT_FILE_CHANGE_RATIO = 0.5 \ No newline at end of file +IMPORTANT_FILE_CHANGE_RATIO = 0.5 + +# 파일당 최대 코멘트 수 +MAX_COMMENTS_PER_FILE = 3 \ No newline at end of file From 506037b092669fe3db350902f826ffb7fe19ff17 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Tue, 8 Oct 2024 22:46:54 +0900 Subject: [PATCH 40/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 개별 코멘트 비활성화 --- .github/scripts/ai_code_review.py | 64 +++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index d7e94c0..e3b7512 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -329,39 +329,39 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): review_prompt = get_review_prompt(all_code) overall_review = review_code_groq(review_prompt) - # 중요 파일에 대한 상세 리뷰 - for file in important_files: - logger.info(f"중요 파일 상세 리뷰 중: {file['filename']}") - if file['status'] == 'removed': - file_review = f"파일 '{file['filename']}'이(가) 삭제되었습니다. 이 변경이 적절한지 확인해 주세요." - else: - content = requests.get(file['raw_url']).text - file_review_prompt = get_file_review_prompt(file['filename'], content) - file_review = review_code_groq(file_review_prompt) + # 중요 파일에 대한 상세 리뷰 (라인 별 코멘트 비활성화) + # for file in important_files: + # logger.info(f"중요 파일 상세 리뷰 중: {file['filename']}") + # if file['status'] == 'removed': + # file_review = f"파일 '{file['filename']}'이(가) 삭제되었습니다. 이 변경이 적절한지 확인해 주세요." + # else: + # content = requests.get(file['raw_url']).text + # file_review_prompt = get_file_review_prompt(file['filename'], content) + # file_review = review_code_groq(file_review_prompt) - # 파일 전체에 대한 리뷰 코멘트 - post_file_comment( - repo, - pr_number, - latest_commit_id, - file['filename'], - file_review, - github_token - ) - - # 라인 별 코멘트 - line_comments_prompt = get_line_comments_prompt(file['filename'], content) - line_comments = review_code_groq(line_comments_prompt) - - post_line_comments( - repo, - pr_number, - latest_commit_id, - file['filename'], - file['patch'], - line_comments, - github_token - ) + # # 파일 전체에 대한 리뷰 코멘트 + # post_file_comment( + # repo, + # pr_number, + # latest_commit_id, + # file['filename'], + # file_review, + # github_token + # ) + + # # 라인 별 코멘트 + # line_comments_prompt = get_line_comments_prompt(file['filename'], content) + # line_comments = review_code_groq(line_comments_prompt) + + # post_line_comments( + # repo, + # pr_number, + # latest_commit_id, + # file['filename'], + # file['patch'], + # line_comments, + # github_token + # ) return overall_review From 21b1ef3abff6e937980a8174d92b3b3cf7cd6e11 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 00:19:15 +0900 Subject: [PATCH 41/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 전체 리뷰 프롬프트 PR 관련 정보 추가 --- .github/scripts/ai_code_review.py | 34 ++++++++++++++++++++++++++++++- scripts/review_prompt.py | 25 +++++++++++++++++++---- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index e3b7512..bf15d23 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -149,6 +149,35 @@ def post_pr_comment(repo, pr_number, body, token): logger.error(f"PR 코멘트 게시 중 오류 발생: {str(e)}") logger.error(f"응답 내용: {response.content if 'response' in locals() else '응답 없음'}") +def get_pr_context(repo, pr_number, github_token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" + headers = { + "Authorization": f"Bearer {github_token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + response = requests.get(url, headers=headers) + response.raise_for_status() + pr_data = response.json() + return { + "title": pr_data['title'], + "description": pr_data['body'], + "base_branch": pr_data['base']['ref'], + "head_branch": pr_data['head']['ref'], + } + +def get_commit_messages(repo, pr_number, github_token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/commits" + headers = { + "Authorization": f"Bearer {github_token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28" + } + response = requests.get(url, headers=headers) + response.raise_for_status() + commits = response.json() + return [commit['commit']['message'] for commit in commits] + def post_line_comments(repo, pr_number, commit_sha, filename, patch, line_comments, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" headers = { @@ -324,9 +353,12 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): if not all_code: logger.warning("리뷰할 코드가 없습니다. 모든 파일 내용을 가져오는 데 실패했습니다.") return None, [] + + pr_context = get_pr_context(repo, pr_number, github_token) + commit_messages = get_commit_messages(repo, pr_number, github_token) # 전체 코드에 대한 간략한 리뷰 - review_prompt = get_review_prompt(all_code) + review_prompt = get_review_prompt(all_code, pr_context, commit_messages) overall_review = review_code_groq(review_prompt) # 중요 파일에 대한 상세 리뷰 (라인 별 코멘트 비활성화) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 4f15f90..86fe7b1 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,5 +1,13 @@ REVIEW_PROMPT = """ -당신은 전문적인 코드 리뷰어입니다. 주어진 코드를 분석하고 다음 형식으로 리뷰를 제공해주세요: +당신은 전문적인 코드 리뷰어입니다. +다음은 해당 PR 정보입니다. +- 제목: {title} +- 설명: {description} +- Base 브랜치: {base_branch} +- Head 브랜치: {head_branch} +- 커밋 메시지: {commit_messages} + +주어진 코드를 분석하고 다음 형식으로 리뷰를 제공해주세요: ## 전체 코드 리뷰 @@ -13,9 +21,10 @@ [구체적인 개선 제안, 코드 예시 포함] 전체 코드: -{code} +{all_code} 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. +PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. """ FILE_REVIEW_PROMPT = """ @@ -52,8 +61,16 @@ {overall_review} """ -def get_review_prompt(code): - return REVIEW_PROMPT.format(code=code) +def get_review_prompt(all_code, pr_context, commit_messages): + formatted_commit_messages = "\n".join([f"- {msg}" for msg in commit_messages]) + return REVIEW_PROMPT.format( + title=pr_context['title'], + description=pr_context['description'], + base_branch=pr_context['base_branch'], + head_branch=pr_context['head_branch'], + commit_messages=formatted_commit_messages, + all_code=all_code + ) def get_file_review_prompt(filename, content): return FILE_REVIEW_PROMPT.format(filename=filename, content=content) From b0d522e7adf2b7f387e09730a12f8ab6cb999677 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 00:44:53 +0900 Subject: [PATCH 42/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 53 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index bf15d23..4cd2d7e 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -57,8 +57,7 @@ def get_latest_commit_id(repo, pr_number, token): pr_data = response.json() return pr_data['head']['sha'] -def review_code_groq(pr_content): - prompt = get_review_prompt(pr_content) +def review_code_groq(prompt): try: response = groq_client.chat.completions.create( model="llama-3.1-70b-versatile", @@ -74,30 +73,30 @@ def review_code_groq(pr_content): logger.error(f"Groq API 호출 중 오류 발생: {str(e)}") return f"코드 리뷰 중 발생한 에러: {str(e)}" -def review_code_ollama(pr_content): - prompt = get_review_prompt(pr_content) - url = 'http://localhost:11434/api/generate' - data = { - "model": "llama3.1", - "prompt": prompt, - "stream": False, - "options": { - "temperature": 0.7, - "top_p": 0.8, - "top_k": 40, - "num_predict": 1024 - } - } - logger.debug(f"코드 리뷰 중. URL: {url}") - logger.debug(f"요청 데이터: {data}") - - try: - response = requests.post(url, json=data) - response.raise_for_status() - return response.json()['response'] - except requests.RequestException as e: - logger.error(f"코드 리뷰 중 오류 발생: {str(e)}") - return f"코드 리뷰 중 발생한 에러: {str(e)}" +# def review_code_ollama(pr_content): +# prompt = get_review_prompt(pr_content) +# url = 'http://localhost:11434/api/generate' +# data = { +# "model": "llama3.1", +# "prompt": prompt, +# "stream": False, +# "options": { +# "temperature": 0.7, +# "top_p": 0.8, +# "top_k": 40, +# "num_predict": 1024 +# } +# } +# logger.debug(f"코드 리뷰 중. URL: {url}") +# logger.debug(f"요청 데이터: {data}") + +# try: +# response = requests.post(url, json=data) +# response.raise_for_status() +# return response.json()['response'] +# except requests.RequestException as e: +# logger.error(f"코드 리뷰 중 오류 발생: {str(e)}") +# return f"코드 리뷰 중 발생한 에러: {str(e)}" def post_review_comment(repo, pr_number, commit_sha, path, position, body, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" @@ -357,7 +356,7 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): pr_context = get_pr_context(repo, pr_number, github_token) commit_messages = get_commit_messages(repo, pr_number, github_token) - # 전체 코드에 대한 간략한 리뷰 + # 전체 코드에 대한 리뷰 review_prompt = get_review_prompt(all_code, pr_context, commit_messages) overall_review = review_code_groq(review_prompt) From a6458998cf3957ddbbcc2204be73f38239132c14 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 02:22:52 +0900 Subject: [PATCH 43/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 4 ++-- scripts/review_prompt.py | 39 +++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 4cd2d7e..51591ae 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -447,11 +447,11 @@ def main(): ) if overall_review: - comment = get_total_comments_prompt(overall_review) + # comment = get_total_comments_prompt(overall_review) post_pr_comment( repo, pr_number, - comment, + overall_review, github_token ) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 86fe7b1..c0b2aa3 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,30 +1,49 @@ REVIEW_PROMPT = """ -당신은 전문적인 코드 리뷰어입니다. +당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어이며, 특히 [특정 기술 스택/도메인]에 깊은 전문성을 가지고 있습니다. 다음은 해당 PR 정보입니다. - 제목: {title} - 설명: {description} - Base 브랜치: {base_branch} - Head 브랜치: {head_branch} - 커밋 메시지: {commit_messages} +- 변경된 파일: {changed_files} +- 전체 코드: {all_code} -주어진 코드를 분석하고 다음 형식으로 리뷰를 제공해주세요: +주어진 코드와 PR 정보를 철저히 분석 및 검토하고 다음 형식으로 종합적인 리뷰를 제공해주세요: ## 전체 코드 리뷰 -### 좋은 점 -[좋은 점 나열] +### 요약 (100단어 이내) +[PR의 전반적인 품질, 범위, 영향에 대한 간결한 요약] -### 개선할 점 -[개선이 필요한 점 나열] +### 긍정적인 측면 (2-3개) +- [잘 작성된 부분이나 좋은 실행례] +- [각 항목에 대한 간단한 설명 추가] -### 제안 사항 -[구체적인 개선 제안, 코드 예시 포함] +### 주요 발견 사항 (최대 5개) +1. [가장 중요한 문제나 개선점] + - 영향: [해당 문제가 코드/프로젝트에 미치는 영향] + - 심각도: [높음/중간/낮음] + +### 개선을 위한 제안 (3-5개) +1. [구체적인 개선 방안] + - 현재 코드: [문제가 있는 현재 코드 스니펫] + - 제안된 변경: [개선된 코드 예시] + - 이유: [왜 이 변경이 더 나은지 설명] + +### 추가 고려 사항 +- 성능: [성능 관련 문제나 최적화 기회] +- 보안: [잠재적인 보안 문제나 개선점] +- 테스트: [테스트 커버리지나 품질에 대한 의견] +- 문서화: [문서화 개선 필요 사항] -전체 코드: -{all_code} +### 결론 +- 권장 사항: [승인/변경 후 승인/거부 중 하나 선택] +- 이유: [최종 권장 사항에 대한 간단한 설명] 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. +또한, 프로젝트의 전반적인 아키텍처, 코딩 표준, 그리고 팀의 모범 사례를 고려하여 리뷰를 진행해 주세요. """ FILE_REVIEW_PROMPT = """ From ecc1e90861e6a8ad65bdbc653b266b4bf6d14980 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 02:41:58 +0900 Subject: [PATCH 44/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 34 +++++++++++++++++++++++++++++-- scripts/review_prompt.py | 3 ++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 51591ae..6624295 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -177,6 +177,33 @@ def get_commit_messages(repo, pr_number, github_token): commits = response.json() return [commit['commit']['message'] for commit in commits] +def get_changed_files(repo, pr_number, github_token): + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" + headers = { + "Authorization": f"token {github_token}", + "Accept": "application/vnd.github.v3+json" + } + response = requests.get(url, headers=headers) + files = response.json() + + changed_files_info = [] + for file in files: + status = file['status'] + filename = file['filename'] + additions = file['additions'] + deletions = file['deletions'] + + if status == 'added': + info = f"{filename} (추가, +{additions}, -0)" + elif status == 'removed': + info = f"{filename} (삭제)" + else: + info = f"{filename} (수정, +{additions}, -{deletions})" + + changed_files_info.append(info) + + return "\n".join(f"{i+1}. {info}" for i, info in enumerate(changed_files_info)) + def post_line_comments(repo, pr_number, commit_sha, filename, patch, line_comments, token): url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/comments" headers = { @@ -355,9 +382,12 @@ def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): pr_context = get_pr_context(repo, pr_number, github_token) commit_messages = get_commit_messages(repo, pr_number, github_token) + changed_files = get_changed_files(repo, pr_number, github_token) - # 전체 코드에 대한 리뷰 - review_prompt = get_review_prompt(all_code, pr_context, commit_messages) + # 개선된 리뷰 프롬프트 생성 + review_prompt = get_review_prompt(all_code, pr_context, commit_messages, changed_files) + + # 전체 코드에 대한 상세한 리뷰 overall_review = review_code_groq(review_prompt) # 중요 파일에 대한 상세 리뷰 (라인 별 코멘트 비활성화) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index c0b2aa3..79174e5 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -80,7 +80,7 @@ {overall_review} """ -def get_review_prompt(all_code, pr_context, commit_messages): +def get_review_prompt(all_code, pr_context, commit_messages, changed_files): formatted_commit_messages = "\n".join([f"- {msg}" for msg in commit_messages]) return REVIEW_PROMPT.format( title=pr_context['title'], @@ -88,6 +88,7 @@ def get_review_prompt(all_code, pr_context, commit_messages): base_branch=pr_context['base_branch'], head_branch=pr_context['head_branch'], commit_messages=formatted_commit_messages, + changed_files=changed_files, all_code=all_code ) From 1d802e1430761db29937046f1086fa38256033d5 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 03:44:09 +0900 Subject: [PATCH 45/74] =?UTF-8?q?feat(BE):=20AI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=A3=BC=EC=9A=94=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=84=A0=EB=B3=84=20=EA=B0=80=EC=A4=91=EC=B9=98=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 72 ++++++++++++++++++++++++++++--- .github/scripts/review_config.py | 1 - 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 6624295..8c32d9b 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -337,7 +337,56 @@ def fetch_pr_data(repo, pr_number, github_token): latest_commit_id = get_latest_commit_id(repo, pr_number, github_token) return pr_files, latest_commit_id -def is_important_file(file): +def get_importance_threshold(file, total_pr_changes): + base_threshold = 0.5 # 기본 임계값을 0.5로 설정 (더 많은 파일을 중요하게 간주) + + # 파일 확장자에 따른 가중치 + extension_weights = { + # 백엔드 파일 (높은 가중치) + '.py': 1.2, # Python 파일 + + # 프론트엔드 파일 (높은 가중치) + '.js': 1.2, # JavaScript 파일 + '.jsx': 1.2, # React JSX 파일 + '.ts': 1.2, # TypeScript 파일 + '.tsx': 1.2, # React TypeScript 파일 + + # 스타일 파일 (중간 가중치) + '.css': 1.0, # CSS 파일 + '.scss': 1.0, # SCSS 파일 + + # 설정 파일 (낮은 가중치) + '.json': 0.9, # JSON 설정 파일 + '.yml': 0.9, # YAML 설정 파일 + '.env': 0.9, # 환경 변수 파일 + + # 문서 파일 (가장 낮은 가중치) + '.md': 0.7, # Markdown 문서 + '.txt': 0.7, # 텍스트 문서 + } + + # 파일 확장자 추출 + _, ext = os.path.splitext(file['filename']) + + # 확장자에 따른 가중치 적용 (기본값 1.0) + weight = extension_weights.get(ext.lower(), 1.0) + + # PR 전체 변경 크기에 따른 조정 (팀 규모가 작으므로 기준을 낮춤) + if total_pr_changes > 500: # 대규모 PR 기준을 500줄로 낮춤 + base_threshold *= 0.9 # 대규모 PR의 경우 임계값 낮춤 + elif total_pr_changes < 50: # 소규모 PR 기준을 50줄로 낮춤 + base_threshold *= 1.1 # 소규모 PR의 경우 임계값 높임 + + # 파일 크기에 따른 조정 + file_size = file.get('changes', 0) + if file_size < 30: # 작은 파일 기준을 30줄로 낮춤 + base_threshold *= 1.2 # 작은 파일의 경우 임계값 높임 + elif file_size > 300: # 큰 파일 기준을 300줄로 낮춤 + base_threshold *= 0.8 # 큰 파일의 경우 임계값 낮춤 + + return min(base_threshold * weight, 1.0) # 최대값을 1.0으로 제한 + +def is_important_file(file, total_pr_changes): filename = file['filename'] if filename in IGNORED_FILES: logger.debug(f"무시된 파일: {filename}") @@ -351,22 +400,31 @@ def is_important_file(file): logger.info(f"삭제된 파일: {file['filename']}") return True - total_lines = file.get('additions', 0) + file.get('deletions', 0) - change_ratio = total_lines / file.get('changes', 1) - is_important = file['changes'] > IMPORTANT_FILE_CHANGE_THRESHOLD or change_ratio > IMPORTANT_FILE_CHANGE_RATIO + total_changes = file.get('changes', 0) + additions = file.get('additions', 0) + deletions = file.get('deletions', 0) + + # 변경 비율을 추가와 삭제의 절대값 합으로 계산 (변경의 강도를 계산) + change_ratio = (additions + deletions) / max(total_changes, 1) + importance_threshold = get_importance_threshold(file, total_pr_changes) + + is_important = total_changes > IMPORTANT_FILE_CHANGE_THRESHOLD or change_ratio > importance_threshold if is_important: - logger.info(f"중요 파일로 선정: {file['filename']} (변경: {file['changes']}줄, 비율: {change_ratio:.2f})") + logger.info(f"중요 파일로 선정: {filename} (변경: {total_changes}줄, 추가: {additions}, 삭제: {deletions}, 비율: {change_ratio:.2f}, 임계값: {importance_threshold:.2f})") else: - logger.debug(f"일반 파일: {file['filename']} (변경: {file['changes']}줄, 비율: {change_ratio:.2f})") + logger.debug(f"일반 파일: {filename} (변경: {total_changes}줄, 추가: {additions}, 삭제: {deletions}, 비율: {change_ratio:.2f}, 임계값: {importance_threshold:.2f})") return is_important def generate_reviews(pr_files, repo, pr_number, latest_commit_id, github_token): all_code = "" - important_files = [f for f in pr_files if is_important_file(f)] + total_pr_changes = sum(file.get('changes', 0) for file in pr_files) + + important_files = [f for f in pr_files if is_important_file(f, total_pr_changes)] logger.info(f"총 {len(pr_files)}개 파일 중 {len(important_files)}개 파일이 중요 파일로 선정되었습니다.") + logger.info(f"PR 전체 변경 크기: {total_pr_changes}줄") for file in pr_files: if file['status'] == 'removed': diff --git a/.github/scripts/review_config.py b/.github/scripts/review_config.py index 39cfae0..239d314 100644 --- a/.github/scripts/review_config.py +++ b/.github/scripts/review_config.py @@ -22,7 +22,6 @@ # 중요 파일 판단 기준 IMPORTANT_FILE_CHANGE_THRESHOLD = 100 -IMPORTANT_FILE_CHANGE_RATIO = 0.5 # 파일당 최대 코멘트 수 MAX_COMMENTS_PER_FILE = 3 \ No newline at end of file From d8309dbd0802c33a55d7397228f4a2c301ea5eca Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 03:44:22 +0900 Subject: [PATCH 46/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 79174e5..63b4f5f 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,5 +1,6 @@ REVIEW_PROMPT = """ -당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어이며, 특히 [특정 기술 스택/도메인]에 깊은 전문성을 가지고 있습니다. +당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. +특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. 다음은 해당 PR 정보입니다. - 제목: {title} - 설명: {description} @@ -31,16 +32,6 @@ - 제안된 변경: [개선된 코드 예시] - 이유: [왜 이 변경이 더 나은지 설명] -### 추가 고려 사항 -- 성능: [성능 관련 문제나 최적화 기회] -- 보안: [잠재적인 보안 문제나 개선점] -- 테스트: [테스트 커버리지나 품질에 대한 의견] -- 문서화: [문서화 개선 필요 사항] - -### 결론 -- 권장 사항: [승인/변경 후 승인/거부 중 하나 선택] -- 이유: [최종 권장 사항에 대한 간단한 설명] - 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. 또한, 프로젝트의 전반적인 아키텍처, 코딩 표준, 그리고 팀의 모범 사례를 고려하여 리뷰를 진행해 주세요. From 2b0a6bfbf89d0bebdb44b42a87541c530d62a25f Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 03:47:18 +0900 Subject: [PATCH 47/74] =?UTF-8?q?fix(BE):=20import=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 8c32d9b..a9cf284 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -9,7 +9,6 @@ IGNORED_EXTENSIONS, IGNORED_FILES, IMPORTANT_FILE_CHANGE_THRESHOLD, - IMPORTANT_FILE_CHANGE_RATIO, MAX_COMMENTS_PER_FILE ) From 3cb0cebbcae7da60ba0d358a8c108e144167b0a4 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 04:10:49 +0900 Subject: [PATCH 48/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 가중치에서 파일의 전체 크기 대비 변경된 라인 수의 비율 비교 --- .github/scripts/ai_code_review.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index a9cf284..b64c7c2 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -403,8 +403,8 @@ def is_important_file(file, total_pr_changes): additions = file.get('additions', 0) deletions = file.get('deletions', 0) - # 변경 비율을 추가와 삭제의 절대값 합으로 계산 (변경의 강도를 계산) - change_ratio = (additions + deletions) / max(total_changes, 1) + # 파일의 전체 크기 대비 변경된 라인 수의 비율 + change_ratio = total_changes / total_pr_changes if total_pr_changes > 0 else 0 importance_threshold = get_importance_threshold(file, total_pr_changes) is_important = total_changes > IMPORTANT_FILE_CHANGE_THRESHOLD or change_ratio > importance_threshold From 2c0e684a005a34ce5a84bd3bc2eaee5a81679403 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 04:47:35 +0900 Subject: [PATCH 49/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 4 +--- scripts/review_prompt.py | 10 +++------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index b64c7c2..b7ea026 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -159,9 +159,7 @@ def get_pr_context(repo, pr_number, github_token): pr_data = response.json() return { "title": pr_data['title'], - "description": pr_data['body'], - "base_branch": pr_data['base']['ref'], - "head_branch": pr_data['head']['ref'], + "description": pr_data['body'] } def get_commit_messages(repo, pr_number, github_token): diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 63b4f5f..b261ba9 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -4,13 +4,13 @@ 다음은 해당 PR 정보입니다. - 제목: {title} - 설명: {description} -- Base 브랜치: {base_branch} -- Head 브랜치: {head_branch} - 커밋 메시지: {commit_messages} - 변경된 파일: {changed_files} - 전체 코드: {all_code} -주어진 코드와 PR 정보를 철저히 분석 및 검토하고 다음 형식으로 종합적인 리뷰를 제공해주세요: +PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. + +철저히 분석 및 검토하여 반드시 아래와 같은 형식으로 종합적인 리뷰를 제공해주세요: ## 전체 코드 리뷰 @@ -33,8 +33,6 @@ - 이유: [왜 이 변경이 더 나은지 설명] 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. -PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. -또한, 프로젝트의 전반적인 아키텍처, 코딩 표준, 그리고 팀의 모범 사례를 고려하여 리뷰를 진행해 주세요. """ FILE_REVIEW_PROMPT = """ @@ -76,8 +74,6 @@ def get_review_prompt(all_code, pr_context, commit_messages, changed_files): return REVIEW_PROMPT.format( title=pr_context['title'], description=pr_context['description'], - base_branch=pr_context['base_branch'], - head_branch=pr_context['head_branch'], commit_messages=formatted_commit_messages, changed_files=changed_files, all_code=all_code From 1670fe4e7e7b1826f54d48dc5100fe31605862be Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 04:53:58 +0900 Subject: [PATCH 50/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index b261ba9..33fc2b4 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -6,25 +6,17 @@ - 설명: {description} - 커밋 메시지: {commit_messages} - 변경된 파일: {changed_files} -- 전체 코드: {all_code} PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. - 철저히 분석 및 검토하여 반드시 아래와 같은 형식으로 종합적인 리뷰를 제공해주세요: ## 전체 코드 리뷰 -### 요약 (100단어 이내) -[PR의 전반적인 품질, 범위, 영향에 대한 간결한 요약] - -### 긍정적인 측면 (2-3개) -- [잘 작성된 부분이나 좋은 실행례] -- [각 항목에 대한 간단한 설명 추가] +### 개선할 점 +[개선이 필요한 점 나열] -### 주요 발견 사항 (최대 5개) -1. [가장 중요한 문제나 개선점] - - 영향: [해당 문제가 코드/프로젝트에 미치는 영향] - - 심각도: [높음/중간/낮음] +### 제안 사항 +[구체적인 개선 제안, 코드 예시 포함] ### 개선을 위한 제안 (3-5개) 1. [구체적인 개선 방안] @@ -32,6 +24,8 @@ - 제안된 변경: [개선된 코드 예시] - 이유: [왜 이 변경이 더 나은지 설명] +전체 코드: {all_code} + 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. """ From 302b13d22d6ba1af1f4d08b0756694bc33ba6ef2 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:01:38 +0900 Subject: [PATCH 51/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - llama-3.2-90b-text-preview --- .github/scripts/ai_code_review.py | 4 ++-- scripts/review_prompt.py | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index b7ea026..037665f 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -59,9 +59,9 @@ def get_latest_commit_id(repo, pr_number, token): def review_code_groq(prompt): try: response = groq_client.chat.completions.create( - model="llama-3.1-70b-versatile", + model="llama-3.2-90b-text-preview", messages=[ - {"role": "system", "content": "You are an expert code reviewer."}, + {"role": "system", "content": "당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. 특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. "}, {"role": "user", "content": prompt} ], temperature=0.7, diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 33fc2b4..01dca2c 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,6 +1,4 @@ REVIEW_PROMPT = """ -당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. -특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. 다음은 해당 PR 정보입니다. - 제목: {title} - 설명: {description} @@ -13,12 +11,12 @@ ## 전체 코드 리뷰 ### 개선할 점 -[개선이 필요한 점 나열] +[개선이 필요한 점 최대 5가지] ### 제안 사항 -[구체적인 개선 제안, 코드 예시 포함] +[코드 예시 포함 구체적인 개선 제안] -### 개선을 위한 제안 (3-5개) +### 개선을 위한 제안 1. [구체적인 개선 방안] - 현재 코드: [문제가 있는 현재 코드 스니펫] - 제안된 변경: [개선된 코드 예시] From 2febe061d314591f7700fdd9babf042b6804e3f6 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:07:35 +0900 Subject: [PATCH 52/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - llama3-70b-8192 --- .github/scripts/ai_code_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 037665f..82a4b08 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -59,7 +59,7 @@ def get_latest_commit_id(repo, pr_number, token): def review_code_groq(prompt): try: response = groq_client.chat.completions.create( - model="llama-3.2-90b-text-preview", + model="llama3-70b-8192", messages=[ {"role": "system", "content": "당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. 특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. "}, {"role": "user", "content": prompt} From 68911c08dfd2d82d6539c6669be769cd2c24d6fd Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:09:19 +0900 Subject: [PATCH 53/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - llama-3.1-70b-versatile --- .github/scripts/ai_code_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 82a4b08..14b93bf 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -59,7 +59,7 @@ def get_latest_commit_id(repo, pr_number, token): def review_code_groq(prompt): try: response = groq_client.chat.completions.create( - model="llama3-70b-8192", + model="llama-3.1-70b-versatile", messages=[ {"role": "system", "content": "당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. 특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. "}, {"role": "user", "content": prompt} From 8be7c16cb29b1afd508cc4a1e1b84175fd7acf79 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:20:34 +0900 Subject: [PATCH 54/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 01dca2c..3f480a6 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -6,25 +6,39 @@ - 변경된 파일: {changed_files} PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. -철저히 분석 및 검토하여 반드시 아래와 같은 형식으로 종합적인 리뷰를 제공해주세요: +철저히 분석 및 검토하여 반드시 아래와 같은 형식을 엄격하게 지켜서 종합적인 리뷰를 제공해주세요: ## 전체 코드 리뷰 -### 개선할 점 +### 🧑🏻‍💻 개선할 점 + [개선이 필요한 점 최대 5가지] -### 제안 사항 +### 🔍 제안 사항 + [코드 예시 포함 구체적인 개선 제안] -### 개선을 위한 제안 +### 📢 개선을 위한 제안 + 1. [구체적인 개선 방안] - - 현재 코드: [문제가 있는 현재 코드 스니펫] - - 제안된 변경: [개선된 코드 예시] - - 이유: [왜 이 변경이 더 나은지 설명] + + - 현재 코드 + + [문제가 있는 현재 코드 스니펫] + + - 제안된 변경 + + [개선된 코드 예시] + + - 이유 + + [왜 이 변경이 더 나은지 설명] 전체 코드: {all_code} 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. +코드를 표현할 때는 반드시 백틱(```) 세 개로 둘러싸인 코드 블록을 사용하는데 꼭 들여쓰기를 잘 신경써주세요. + """ FILE_REVIEW_PROMPT = """ From a154687e14e6614bf03b412285f72210a7fc1f40 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:26:00 +0900 Subject: [PATCH 55/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 3f480a6..906efad 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -37,8 +37,18 @@ 전체 코드: {all_code} 응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. -코드를 표현할 때는 반드시 백틱(```) 세 개로 둘러싸인 코드 블록을 사용하는데 꼭 들여쓰기를 잘 신경써주세요. + ```python +[내용] +``` + +코드 박스 응답값을 자꾸 위에 형태로 전달받아서 코드 박스가 계속 깨집니다. + +```python + [내용] +``` + +이렇게 작성하여 응답값이 깔끔하게 출력되도록 꼭 들여쓰기를 신경써주세요 """ FILE_REVIEW_PROMPT = """ From 8b53d9114cec39cd67aa644ef6b0d823e3e54729 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:29:38 +0900 Subject: [PATCH 56/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 906efad..a8e8f76 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -7,7 +7,7 @@ PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. 철저히 분석 및 검토하여 반드시 아래와 같은 형식을 엄격하게 지켜서 종합적인 리뷰를 제공해주세요: - +-------------------------------------------------------- ## 전체 코드 리뷰 ### 🧑🏻‍💻 개선할 점 @@ -22,33 +22,23 @@ 1. [구체적인 개선 방안] - - 현재 코드 + 1️⃣ 현재 코드 [문제가 있는 현재 코드 스니펫] - - 제안된 변경 + 2️⃣ 제안된 변경 [개선된 코드 예시] - - 이유 + 3️⃣ 이유 [왜 이 변경이 더 나은지 설명] -전체 코드: {all_code} - -응답은 위의 형식을 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. +-------------------------------------------------------- - ```python -[내용] -``` - -코드 박스 응답값을 자꾸 위에 형태로 전달받아서 코드 박스가 계속 깨집니다. - -```python - [내용] -``` +전체 코드: {all_code} -이렇게 작성하여 응답값이 깔끔하게 출력되도록 꼭 들여쓰기를 신경써주세요 +응답은 꼭 위의 형식을 엄격하게 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. """ FILE_REVIEW_PROMPT = """ From e0f5707ddf12ee298f79b29347c6dca1051590eb Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:32:08 +0900 Subject: [PATCH 57/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 14b93bf..fc1760b 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -59,7 +59,7 @@ def get_latest_commit_id(repo, pr_number, token): def review_code_groq(prompt): try: response = groq_client.chat.completions.create( - model="llama-3.1-70b-versatile", + model="llama-3.2-11b-vision-preview", messages=[ {"role": "system", "content": "당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. 특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. "}, {"role": "user", "content": prompt} From 36c9462d72cf1b2e38b1e4883332c54d9dff8ff8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:37:58 +0900 Subject: [PATCH 58/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 2 +- scripts/review_prompt.py | 23 +++++++++-------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index fc1760b..14b93bf 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -59,7 +59,7 @@ def get_latest_commit_id(repo, pr_number, token): def review_code_groq(prompt): try: response = groq_client.chat.completions.create( - model="llama-3.2-11b-vision-preview", + model="llama-3.1-70b-versatile", messages=[ {"role": "system", "content": "당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. 특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. "}, {"role": "user", "content": prompt} diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index a8e8f76..528fabf 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -14,26 +14,21 @@ [개선이 필요한 점 최대 5가지] -### 🔍 제안 사항 +### 📢 개선을 위한 제안 -[코드 예시 포함 구체적인 개선 제안] +0️⃣ 구체적인 개선 방안 -### 📢 개선을 위한 제안 +1️⃣ 현재 코드 + +[문제가 있는 현재 코드 스니펫] -1. [구체적인 개선 방안] +2️⃣ 제안된 변경 - 1️⃣ 현재 코드 - - [문제가 있는 현재 코드 스니펫] +[개선된 코드 예시] - 2️⃣ 제안된 변경 - - [개선된 코드 예시] - - 3️⃣ 이유 - - [왜 이 변경이 더 나은지 설명] +3️⃣ 이유 +[왜 이 변경이 더 나은지 설명] -------------------------------------------------------- 전체 코드: {all_code} From b140c0296867801663d56a1934ed50aefae57f5d Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:44:47 +0900 Subject: [PATCH 59/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 528fabf..bec72d1 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -12,23 +12,17 @@ ### 🧑🏻‍💻 개선할 점 -[개선이 필요한 점 최대 5가지] +- 개선이 필요한 점 최대 5가지 ### 📢 개선을 위한 제안 -0️⃣ 구체적인 개선 방안 +- 구체적인 개선 방안 -1️⃣ 현재 코드 +- 현재 코드 -[문제가 있는 현재 코드 스니펫] +- 제안된 변경 -2️⃣ 제안된 변경 - -[개선된 코드 예시] - -3️⃣ 이유 - -[왜 이 변경이 더 나은지 설명] +- 이유 -------------------------------------------------------- 전체 코드: {all_code} From 74b14360947b8f4d2eba567b163769d73f0e8d9c Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 05:52:26 +0900 Subject: [PATCH 60/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/ai_code_review.py | 2 +- scripts/review_prompt.py | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index 14b93bf..b8da6f4 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -61,7 +61,7 @@ def review_code_groq(prompt): response = groq_client.chat.completions.create( model="llama-3.1-70b-versatile", messages=[ - {"role": "system", "content": "당신은 FANNG 시니어 개발자 출신의 전문적인 코드 리뷰어입니다. 특히 백엔드의 경우 Python, FastAPI, 프론트의 경우 React와 Next.js에 깊은 조예와 전문성을 가지고 있습니다. "}, + {"role": "system", "content": "You are a professional code reviewer from FANNG Senior Developer."}, {"role": "user", "content": prompt} ], temperature=0.7, diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index bec72d1..59de9da 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -1,12 +1,13 @@ REVIEW_PROMPT = """ -다음은 해당 PR 정보입니다. -- 제목: {title} -- 설명: {description} -- 커밋 메시지: {commit_messages} -- 변경된 파일: {changed_files} - -PR 정보와 커밋 메시지를 고려하여 변경 사항의 목적과 맥락을 이해하고 리뷰해 주세요. -철저히 분석 및 검토하여 반드시 아래와 같은 형식을 엄격하게 지켜서 종합적인 리뷰를 제공해주세요: +You have deep knowledge and expertise in Python, FastAPI for the back end, React and Next.js for the front. +Here is the new PR information. +- title: {title} +- description: {description} +- commit messages: {commit_messages} +- changed files: {changed_files} + +Please understand and review the purpose and context of the change considering PR information and commit message. +Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -------------------------------------------------------- ## 전체 코드 리뷰 @@ -25,9 +26,10 @@ - 이유 -------------------------------------------------------- -전체 코드: {all_code} +Full Code: {all_code} -응답은 꼭 위의 형식을 엄격하게 따라 작성해 주시되, 구체적이고 건설적인 피드백을 제공해 주세요. +The person receiving this feedback is a Korean developer. +Please make sure to follow the above format strictly in Korean, but please provide specific and constructive feedback. """ FILE_REVIEW_PROMPT = """ From c598b9816b39a9185f23054d7fb08b3802185dd8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:07:13 +0900 Subject: [PATCH 61/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 59de9da..f45493b 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -9,21 +9,17 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -------------------------------------------------------- -## 전체 코드 리뷰 +### 🧑🏻‍💻 개선 필요(최대 5개 핵심 영역 나열) -### 🧑🏻‍💻 개선할 점 +### 🔍 제안(가능한 경우 코드 예시 제공) -- 개선이 필요한 점 최대 5가지 +### 📢 제안된 솔루션 -### 📢 개선을 위한 제안 + 1. 현재 코드: [문제가 있는 코드 조각] -- 구체적인 개선 방안 + 2. 권장되는 변경: [업데이트된 코드] -- 현재 코드 - -- 제안된 변경 - -- 이유 + 3. 변경 이유: [변경이 더 좋은 이유에 대한 설명] -------------------------------------------------------- Full Code: {all_code} From d01b1a49740dc06c91c295772aaa7f3b912c0854 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:10:57 +0900 Subject: [PATCH 62/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index f45493b..99567cc 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -9,17 +9,17 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -------------------------------------------------------- -### 🧑🏻‍💻 개선 필요(최대 5개 핵심 영역 나열) +## 🧑🏻‍💻 개선 필요(최대 5개 핵심 영역 나열 (최대 공백 포함 70자 내의 한 문장)) -### 🔍 제안(가능한 경우 코드 예시 제공) +## 🔍 제안(가능한 경우 코드 예시 (5줄 이하의 코드) 제공) -### 📢 제안된 솔루션 +## 📢 제안된 솔루션 - 1. 현재 코드: [문제가 있는 코드 조각] + 1. 현재 코드: [문제가 있는 코드 조각 (5줄 이하의 코드)] - 2. 권장되는 변경: [업데이트된 코드] + 2. 권장되는 변경: [업데이트된 코드 (5줄 이하의 코드)] - 3. 변경 이유: [변경이 더 좋은 이유에 대한 설명] + 3. 변경 이유: [변경이 더 좋은 이유에 대한 설명 (최대 공백 포함 70자 내의 한 문장)] -------------------------------------------------------- Full Code: {all_code} From eca1782bfa554ee7b353ed3604b63d135feeb951 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:19:06 +0900 Subject: [PATCH 63/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=AA=A8=EB=8D=B8=20=EC=98=B5=EC=85=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - max_tokens 2048로 수정 --- .github/scripts/ai_code_review.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/ai_code_review.py b/.github/scripts/ai_code_review.py index b8da6f4..55490ab 100644 --- a/.github/scripts/ai_code_review.py +++ b/.github/scripts/ai_code_review.py @@ -65,7 +65,7 @@ def review_code_groq(prompt): {"role": "user", "content": prompt} ], temperature=0.7, - max_tokens=1024 + max_tokens=2048 ) return response.choices[0].message.content except Exception as e: From a77808ceb30044209218354ee89653ab47500627 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:39:02 +0900 Subject: [PATCH 64/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 99567cc..62f09d0 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -9,21 +9,34 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -------------------------------------------------------- -## 🧑🏻‍💻 개선 필요(최대 5개 핵심 영역 나열 (최대 공백 포함 70자 내의 한 문장)) +## 🧑🏻‍💻 주요 기능 -## 🔍 제안(가능한 경우 코드 예시 (5줄 이하의 코드) 제공) +[핵심 기능, 입력 및 출력 예상, 처리하는 특정 예외 사례를 포함하여 이 파일의 주요 기능에 대한 간략한 설명을 제공하세요] + +## 🔍 개선할 점 + +[성능 병목 현상, 가독성 문제, 보안 취약점 등 개선이 필요한 모든 영역을 나열합니다.] ## 📢 제안된 솔루션 - 1. 현재 코드: [문제가 있는 코드 조각 (5줄 이하의 코드)] +1. 현재 코드 + +[문제가 있는 코드 조각] - 2. 권장되는 변경: [업데이트된 코드 (5줄 이하의 코드)] +2. 권장되는 변경 - 3. 변경 이유: [변경이 더 좋은 이유에 대한 설명 (최대 공백 포함 70자 내의 한 문장)] +[업데이트된 코드 조각] + +3. 변경 이유 + +[성능, 가독성, 보안 등을 고려하여 새로운 접근 방식이 더 나은 간략한 이유] -------------------------------------------------------- Full Code: {all_code} +If you have to put in a code block, please put only the code that needs to be improved briefly. +Please write one sentence within 70 characters, including the maximum space, that you need to explain. + The person receiving this feedback is a Korean developer. Please make sure to follow the above format strictly in Korean, but please provide specific and constructive feedback. """ From a48344be55f1673c18620453353a07e6efac906c Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:41:45 +0900 Subject: [PATCH 65/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 62f09d0..24f67b0 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -36,6 +36,7 @@ If you have to put in a code block, please put only the code that needs to be improved briefly. Please write one sentence within 70 characters, including the maximum space, that you need to explain. +If you write one sentence for readability, please write the next sentence in the next column instead of the next one. The person receiving this feedback is a Korean developer. Please make sure to follow the above format strictly in Korean, but please provide specific and constructive feedback. From babd01963f460b80caa4190d52135aabd85ab791 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:47:07 +0900 Subject: [PATCH 66/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 24f67b0..8d21f64 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -35,6 +35,7 @@ Full Code: {all_code} If you have to put in a code block, please put only the code that needs to be improved briefly. +Write only the part where major changes are made within the code block and omit the rest as '...' to make it as short as possible. Please write one sentence within 70 characters, including the maximum space, that you need to explain. If you write one sentence for readability, please write the next sentence in the next column instead of the next one. From c08927005ad38e352eb1b41a2906b61521872a58 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:48:59 +0900 Subject: [PATCH 67/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 8d21f64..24f67b0 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -35,7 +35,6 @@ Full Code: {all_code} If you have to put in a code block, please put only the code that needs to be improved briefly. -Write only the part where major changes are made within the code block and omit the rest as '...' to make it as short as possible. Please write one sentence within 70 characters, including the maximum space, that you need to explain. If you write one sentence for readability, please write the next sentence in the next column instead of the next one. From 3895aceb03e238e67eef78ac312935f8974a7cd7 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:53:54 +0900 Subject: [PATCH 68/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 24f67b0..10ababc 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -8,6 +8,7 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. +Please find the 1st priority that needs to be improved from the total code you have provided and fill it out in the format below. -------------------------------------------------------- ## 🧑🏻‍💻 주요 기능 From d7d12e8880bb1ccfe4da967e12d028dea3ab5018 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:56:12 +0900 Subject: [PATCH 69/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 10ababc..949f373 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -35,7 +35,7 @@ Full Code: {all_code} -If you have to put in a code block, please put only the code that needs to be improved briefly. +If you need to put in a code block, keep it brief, no more than 10 lines of code that needs improvement. Please write one sentence within 70 characters, including the maximum space, that you need to explain. If you write one sentence for readability, please write the next sentence in the next column instead of the next one. From 037e7512e664df01bbaf8378324e9f57f983c3f8 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 06:59:44 +0900 Subject: [PATCH 70/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 949f373..c29fbb5 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -8,7 +8,7 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -Please find the 1st priority that needs to be improved from the total code you have provided and fill it out in the format below. +Find just one area of your current code that needs the most improvement and write it in the format below. -------------------------------------------------------- ## 🧑🏻‍💻 주요 기능 From b8a43e0621aef83aca01c392960c7ab5d5bfc690 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 07:03:15 +0900 Subject: [PATCH 71/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index c29fbb5..949f373 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -8,7 +8,7 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -Find just one area of your current code that needs the most improvement and write it in the format below. +Please find the 1st priority that needs to be improved from the total code you have provided and fill it out in the format below. -------------------------------------------------------- ## 🧑🏻‍💻 주요 기능 From 4469e4b3ac952d652b51956bd69617a681e6bedd Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 07:08:32 +0900 Subject: [PATCH 72/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/review_prompt.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 949f373..4f7ffec 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -12,25 +12,25 @@ -------------------------------------------------------- ## 🧑🏻‍💻 주요 기능 -[핵심 기능, 입력 및 출력 예상, 처리하는 특정 예외 사례를 포함하여 이 파일의 주요 기능에 대한 간략한 설명을 제공하세요] +[Provide a brief description of the main features of this file, including its core functionality, expected input and output, and any specific exception cases it handles.] ## 🔍 개선할 점 -[성능 병목 현상, 가독성 문제, 보안 취약점 등 개선이 필요한 모든 영역을 나열합니다.] +[Write down any areas that need improvement, including performance bottlenecks, readability issues, and security vulnerabilities.] ## 📢 제안된 솔루션 1. 현재 코드 -[문제가 있는 코드 조각] +[problematic code fragment] 2. 권장되는 변경 -[업데이트된 코드 조각] +[updated code snippet] 3. 변경 이유 -[성능, 가독성, 보안 등을 고려하여 새로운 접근 방식이 더 나은 간략한 이유] +[Brief reasons why the new approach is better, considering performance, readability, security, etc.] -------------------------------------------------------- Full Code: {all_code} From e554eb812004666faa89caefe5aaebb845efc550 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 07:51:22 +0900 Subject: [PATCH 73/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/data_processor.py | 12 ++++++++++++ .github/scripts/main.py | 12 ++++++++++++ .github/scripts/test_utils.py | 16 ++++++++++++++++ .github/scripts/utils.py | 18 ++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 .github/scripts/data_processor.py create mode 100644 .github/scripts/main.py create mode 100644 .github/scripts/test_utils.py create mode 100644 .github/scripts/utils.py diff --git a/.github/scripts/data_processor.py b/.github/scripts/data_processor.py new file mode 100644 index 0000000..1cd522c --- /dev/null +++ b/.github/scripts/data_processor.py @@ -0,0 +1,12 @@ +def process_data(data): + processed = [] + for i in range(len(data)): + processed.append(data[i] * 2) + return processed + +def filter_data(data, threshold): + filtered = [] + for item in data: + if item > threshold: + filtered.append(item) + return filtered \ No newline at end of file diff --git a/.github/scripts/main.py b/.github/scripts/main.py new file mode 100644 index 0000000..455604f --- /dev/null +++ b/.github/scripts/main.py @@ -0,0 +1,12 @@ +from data_processor import process_data +from utils import calculate_average, format_output + +def main(): + data = [1, 2, 3, 4, 5] + processed_data = process_data(data) + average = calculate_average(processed_data) + formatted_output = format_output(average) + print(formatted_output) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/.github/scripts/test_utils.py b/.github/scripts/test_utils.py new file mode 100644 index 0000000..eb2d9da --- /dev/null +++ b/.github/scripts/test_utils.py @@ -0,0 +1,16 @@ +import unittest +from utils import calculate_average, is_prime + +class TestUtils(unittest.TestCase): + def test_calculate_average(self): + self.assertEqual(calculate_average([1, 2, 3, 4, 5]), 3) + self.assertEqual(calculate_average([]), 0) + + def test_is_prime(self): + self.assertTrue(is_prime(2)) + self.assertTrue(is_prime(17)) + self.assertFalse(is_prime(4)) + self.assertFalse(is_prime(1)) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/.github/scripts/utils.py b/.github/scripts/utils.py new file mode 100644 index 0000000..821b974 --- /dev/null +++ b/.github/scripts/utils.py @@ -0,0 +1,18 @@ +def calculate_average(numbers): + total = 0 + count = 0 + for num in numbers: + total += num + count += 1 + return total / count if count > 0 else 0 + +def format_output(value): + return f"The result is: {value:.2f}" + +def is_prime(n): + if n < 2: + return False + for i in range(2, n): + if n % i == 0: + return False + return True \ No newline at end of file From 8d85f3ea449093d3a4ed08f1b036b509c06abf20 Mon Sep 17 00:00:00 2001 From: JongHyunJung Date: Wed, 9 Oct 2024 08:05:01 +0900 Subject: [PATCH 74/74] =?UTF-8?q?refactor(BE):=20AI=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=ED=94=84=EB=A1=AC=ED=94=84=ED=8A=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/scripts/data_processor.py | 12 ------------ .github/scripts/utils.py | 2 +- scripts/review_prompt.py | 5 ++++- 3 files changed, 5 insertions(+), 14 deletions(-) delete mode 100644 .github/scripts/data_processor.py diff --git a/.github/scripts/data_processor.py b/.github/scripts/data_processor.py deleted file mode 100644 index 1cd522c..0000000 --- a/.github/scripts/data_processor.py +++ /dev/null @@ -1,12 +0,0 @@ -def process_data(data): - processed = [] - for i in range(len(data)): - processed.append(data[i] * 2) - return processed - -def filter_data(data, threshold): - filtered = [] - for item in data: - if item > threshold: - filtered.append(item) - return filtered \ No newline at end of file diff --git a/.github/scripts/utils.py b/.github/scripts/utils.py index 821b974..f35da12 100644 --- a/.github/scripts/utils.py +++ b/.github/scripts/utils.py @@ -10,7 +10,7 @@ def format_output(value): return f"The result is: {value:.2f}" def is_prime(n): - if n < 2: + if n < 1: return False for i in range(2, n): if n % i == 0: diff --git a/scripts/review_prompt.py b/scripts/review_prompt.py index 4f7ffec..519ca81 100644 --- a/scripts/review_prompt.py +++ b/scripts/review_prompt.py @@ -8,7 +8,10 @@ Please understand and review the purpose and context of the change considering PR information and commit message. Please be sure to thoroughly analyze and review the following format and provide a comprehensive review. -Please find the 1st priority that needs to be improved from the total code you have provided and fill it out in the format below. +If the author has written a post in accordance with the 🙏 review requirements (optional) written in the PR description section, +please provide a solution to resolve the content first. +If not, please find one part of the entire code provided that needs the most improvement and provide a solution. +Please find the number one priority that needs improvement in the entire code you provided and write it strictly in the format below. -------------------------------------------------------- ## 🧑🏻‍💻 주요 기능