코드 리뷰 Github Action 테스트를 위한 일부 코드 리팩토링 #33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Code Review with GPT | |
| on: | |
| pull_request: | |
| types: [opened, synchronize] | |
| workflow_dispatch: | |
| jobs: | |
| code_review: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v3 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.x' | |
| - name: Install dependencies | |
| run: | | |
| pip install openai requests | |
| - name: Generate diff for code review | |
| id: diff | |
| run: | | |
| git fetch origin ${{ github.event.pull_request.base.ref }} --depth=1 | |
| git diff origin/${{ github.event.pull_request.base.ref }} ${{ github.sha }} > pr_diff.txt | |
| shell: bash | |
| - name: Perform Code Review with GPT and Comment on Changed Lines | |
| id: gpt_review | |
| run: | | |
| python <<EOF | |
| import openai | |
| import requests | |
| import json | |
| # OpenAI API Key 설정 | |
| openai.api_key = "${{ secrets.OPENAI_API_KEY }}" | |
| # 시스템 프롬프트 및 모델명 가져오기 | |
| system_prompt = """${{ secrets.SYSTEM_PROMPT }}""" | |
| model_name = "${{ secrets.OPENAI_MODEL }}" | |
| # 처리된 파일과 라인 기록 (중복 방지) | |
| processed_files = set() # 각 파일을 기록 | |
| processed_lines = {} # 각 파일별로 라인을 기록하기 위한 딕셔너리로 수정 | |
| # GitHub API 호출 로그 | |
| print("Fetching changed files from GitHub API...") | |
| # 변경된 파일과 라인 정보를 가져오기 위한 GitHub API 호출 | |
| files_url = f"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | |
| headers = {"Authorization": f"token ${{ secrets.GITHUB_TOKEN }}"} | |
| try: | |
| response = requests.get(files_url, headers=headers, timeout=10) | |
| print(f"GitHub API status code: {response.status_code}") # 상태 코드 로그 출력 | |
| response.raise_for_status() | |
| except requests.exceptions.RequestException as e: | |
| print(f"Error fetching files: {e}") | |
| exit(1) | |
| if response.status_code == 200: | |
| print("Files fetched successfully. Analyzing changes...") | |
| files_changed = response.json() | |
| # .java 파일만 필터링 | |
| java_files = [file for file in files_changed if file['filename'].endswith('.java')] | |
| if not java_files: | |
| print("No .java files to review.") | |
| exit(0) | |
| for file in java_files: | |
| file_path = file['filename'] | |
| # 이미 처리한 파일은 건너뛰기 | |
| if file_path in processed_files: | |
| print(f"Skipping already processed file: {file_path}") | |
| continue | |
| print(f"Processing file: {file_path}") | |
| patch = file.get('patch', '') | |
| print(f"Analyzing patch for file: {file_path}") | |
| # 각 파일마다 중복 라인 처리를 위한 집합 생성 | |
| if file_path not in processed_lines: | |
| processed_lines[file_path] = set() | |
| # 전체 패치 내용을 GPT에게 전달 | |
| if patch: # 패치가 존재할 경우에만 처리 | |
| print(f"Calling GPT API for patch in file: {file_path}") | |
| try: | |
| gpt_response = openai.chat.completions.create( | |
| model=model_name, | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": f"Here is the code diff for context:\n{patch}"} | |
| ], | |
| timeout=30 | |
| ) | |
| except Exception as e: | |
| print(f"Error in GPT request: {e}") | |
| continue | |
| review_comment = gpt_response.choices[0].message.content | |
| print(f"GPT response received for file: {file_path}") | |
| print(f"Review comment: {review_comment}") | |
| # 변경된 파일과 라인에 리뷰 코멘트를 추가 | |
| commit_id = "${{ github.event.pull_request.head.sha }}" | |
| line_number = file.get('patch').split('\n').index(next(line for line in file['patch'].split('\n') if line.startswith('+'))) + 1 | |
| comment_body = { | |
| "body": review_comment, | |
| "path": file_path, | |
| "line": line_number, | |
| "side": "RIGHT", | |
| "commit_id": commit_id | |
| } | |
| # 코멘트를 추가하기 전 파일 경로와 위치를 로그로 출력 | |
| print(f"Commenting on file: {file_path}, line: {line_number}") | |
| comment_url = f"https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments" | |
| response = requests.post(comment_url, headers=headers, data=json.dumps(comment_body)) | |
| # 응답 상태 확인 | |
| if response.status_code == 201: | |
| print(f"Comment posted successfully for file: {file_path}") | |
| else: | |
| print(f"Failed to post comment. Status code: {response.status_code}, Response: {response.text}") | |
| # 각 파일을 처리한 후 파일 이름을 기록 | |
| processed_files.add(file_path) | |
| else: | |
| print(f"Unexpected status code: {response.status_code}") | |
| exit(1) | |
| # 최종 리뷰 요약 코멘트 추가 | |
| final_comment = "### 최종 리뷰 요약: .java 파일에 대한 모든 변경 사항을 검토 완료했습니다." | |
| comment_url = f"https://api.github.com/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" | |
| requests.post(comment_url, headers=headers, data=json.dumps({"body": final_comment})) | |
| print("Final review comment posted.") | |
| exit(0) | |
| EOF |