diff --git a/.github/workflows/code-review.yml b/.github/workflows/code-review.yml index 8e6b610..576479e 100644 --- a/.github/workflows/code-review.yml +++ b/.github/workflows/code-review.yml @@ -7,6 +7,11 @@ on: jobs: review: runs-on: ubuntu-latest + + permissions: + contents: read + pull-requests: write + steps: - name: Checkout code uses: actions/checkout@v3 @@ -20,6 +25,12 @@ jobs: run: | pip install -r requirements.txt - - name: Run code review + - name: Run LLM code review + env: + GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PYTHONPATH: ${{ github.workspace }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_REF: ${{ github.ref }} run: | - python reviewbot/main.py + python3 -m reviewbot.main diff --git a/reviewbot/__pycache__/main.cpython-310.pyc b/reviewbot/__pycache__/main.cpython-310.pyc new file mode 100644 index 0000000..e9b088c Binary files /dev/null and b/reviewbot/__pycache__/main.cpython-310.pyc differ diff --git a/reviewbot/__pycache__/utils.cpython-310.pyc b/reviewbot/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000..446cae4 Binary files /dev/null and b/reviewbot/__pycache__/utils.cpython-310.pyc differ diff --git a/reviewbot/main.py b/reviewbot/main.py index 83c0f30..0b5c570 100644 --- a/reviewbot/main.py +++ b/reviewbot/main.py @@ -1,6 +1,6 @@ import os import requests -from reviewbot.utils import get_diff +from reviewbot.utils import get_diff, post_pr_comment, get_pr_number def review_with_groq(diff): api_key = os.environ.get("GROQ_API_KEY") @@ -9,21 +9,24 @@ def review_with_groq(diff): "Content-Type": "application/json", } payload = { - "model": "mixtral-8x7b-32768", + "model": "meta-llama/llama-4-scout-17b-16e-instruct", "messages": [ {"role": "system", "content": "You are a senior software engineer doing code reviews."}, - {"role": "user", "content": f"Please review this code diff:\n\n{diff}"} + {"role": "user", "content": f"Please review this code diff, list improvements in bullet points:\n\n{diff}"} ], "temperature": 0.3, } response = requests.post("https://api.groq.com/openai/v1/chat/completions", headers=headers, json=payload) + + print("Raw Groq response:", response.status_code, response.text) + response.raise_for_status() return response.json()["choices"][0]["message"]["content"] def main(): diff = get_diff() review = review_with_groq(diff) - print("::notice file=test_module/hello.py,line=1::" + review.replace("\n", " ")) + post_pr_comment(review) if __name__ == "__main__": main() diff --git a/reviewbot/utils.py b/reviewbot/utils.py index dcb02fb..9049894 100644 --- a/reviewbot/utils.py +++ b/reviewbot/utils.py @@ -1,10 +1,64 @@ -# reviewbot/utils.py +import os +import requests +import json + +def get_pr_number(): + event_path = os.getenv("GITHUB_EVENT_PATH") + if not event_path: + raise Exception("GITHUB_EVENT_PATH not set") + + with open(event_path, 'r') as f: + event = json.load(f) + + return event["pull_request"]["number"] def get_diff(): - # In real setup, parse `git diff` or PR files - return "def hello(name):\n print('Hello ' + name)" + repo = os.environ.get("GITHUB_REPOSITORY") # e.g. "owner/repo" + pr_number = get_pr_number() + + token = os.environ.get("GITHUB_TOKEN") + if not token: + raise Exception("Missing GITHUB_TOKEN environment variable.") + + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github.v3+json", + } + + url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files" + + diffs = [] + page = 1 + while True: + response = requests.get(url, headers=headers, params={"page": page, "per_page": 100}) + response.raise_for_status() + files = response.json() + if not files: + break + + for f in files: + patch = f.get("patch") + if patch: + diffs.append(f"File: {f['filename']}\n{patch}") + + page += 1 + + return "\n\n".join(diffs) + +def post_pr_comment(body: str): + repo = os.getenv("GITHUB_REPOSITORY") + token = os.getenv("GITHUB_TOKEN") + pr_number = get_pr_number() + + url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json" + } + payload = { + "body": body + } -def fake_llm_review(diff): - if "print" in diff: - return "Consider using logging instead of print for better production code quality." - return "No issues found." + response = requests.post(url, headers=headers, json=payload) + print("GitHub API response:", response.status_code, response.text) + response.raise_for_status() diff --git a/test_module/hello.py b/test_module/hello.py index 230ef63..eb53221 100644 --- a/test_module/hello.py +++ b/test_module/hello.py @@ -1,6 +1,6 @@ -# test_module/hello.py +# Hello.py: A sample python script used for testing reviews -def hello(name): - print("Hello " + name) - -hello("World") +def helloWorld(): + print("Hello World") + +helloWorld()