From 844cea5098a2b42732ac87d73c882bdcd8d5eb0a Mon Sep 17 00:00:00 2001 From: Jacob Kraniak <113630934+jacob-kraniak@users.noreply.github.com> Date: Tue, 3 Mar 2026 19:38:29 -0500 Subject: [PATCH] Add AI PR review workflow using Grok --- .github/workflows/ai-pr-review | 110 +++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 .github/workflows/ai-pr-review diff --git a/.github/workflows/ai-pr-review b/.github/workflows/ai-pr-review new file mode 100644 index 0000000..a10eab4 --- /dev/null +++ b/.github/workflows/ai-pr-review @@ -0,0 +1,110 @@ +name: Grok AI PR Review + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + pull-requests: write + contents: read + +jobs: + review: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Needed for git diff + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install openai requests + + - name: Run Grok Review + env: + XAI_API_KEY: ${{ secrets.XAI_API_KEY }} + GROK_MODEL: ${{ vars.GROK_MODEL || 'grok-code-fast-1' }} # fallback to fast coding model + run: | + python - << 'EOF' + import os + import requests + from openai import OpenAI + + # Use OpenAI SDK with custom base URL for xAI compatibility + client = OpenAI( + api_key=os.environ["XAI_API_KEY"], + base_url="https://api.x.ai/v1" + ) + + # Get PR diff via GitHub API (or git diff origin/${{ github.base_ref }}...HEAD) + repo = "${{ github.repository }}" + pr_number = ${{ github.event.pull_request.number }} + token = os.environ.get("GITHUB_TOKEN") # built-in + + headers = { + "Accept": "application/vnd.github.v3.diff", + "Authorization": f"token {token}" + } + diff_url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" + diff_response = requests.get(diff_url, headers=headers) + diff_text = diff_response.text + + if not diff_text.strip(): + print("No diff found or empty PR.") + exit(0) + + # Truncate if too long (Grok context is large, but save tokens) + max_chars = 30000 + if len(diff_text) > max_chars: + diff_text = diff_text[:max_chars] + "\n\n[Diff truncated; full context may be larger]" + + # Strong, repo-specific prompt (tune this!) + prompt = f""" + You are a senior security & knowledge-base curator reviewing changes to 'The Book of Secret Knowledge' — a curated list of cybersecurity, pentesting, CLI/GUI tools, shell tricks, and secret-finding resources. + + Review this PR diff carefully: + {diff_text} + + Provide concise, actionable feedback in Markdown: + - **Summary**: One-sentence overview of changes + - **Strengths**: What is good (e.g., new valuable resources, clean formatting) + - **Issues/Suggestions**: + - Formatting/consistency (links, headings, lists) + - Potential inaccuracies or outdated info + - Security risks (e.g., dangerous commands without warnings) + - Improvements (clarity, better structure, missing cross-references) + - **Overall**: Approve, Request changes, or Comment (with emoji rating) + + Be strict but constructive. Flag anything promotional/spammy. + """ + + response = client.chat.completions.create( + model=os.environ["GROK_MODEL"], + messages=[ + {"role": "system", "content": "You are an expert code/knowledge reviewer."}, + {"role": "user", "content": prompt} + ], + temperature=0.4, # lower for focused reviews + max_tokens=1200 + ) + + review_body = response.choices[0].message.content.strip() + + # Post as comment + comment_url = f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments" + comment_headers = { + "Accept": "application/vnd.github+json", + "Authorization": f"Bearer {token}", + "X-GitHub-Api-Version": "2022-11-28" + } + payload = {"body": f"### Grok AI Review\n\n{review_body}"} + requests.post(comment_url, json=payload, headers=comment_headers) + print("Review posted.") + EOF