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