Skip to content

feat(init): add OpenCode tool support #25

feat(init): add OpenCode tool support

feat(init): add OpenCode tool support #25

Workflow file for this run

name: AI PR Review
on:
pull_request_target:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
models: read
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
# Checkout base repo (not PR head) for safe access to CLAUDE.md and proposals.
# The diff is fetched via GitHub API, not from the PR code.
ref: ${{ github.event.pull_request.base.sha }}
fetch-depth: 1
- name: Get PR diff
id: diff
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr diff ${{ github.event.pull_request.number }} > /tmp/pr-full.diff
FULL_SIZE=$(wc -c < /tmp/pr-full.diff)
echo "diff_size=$FULL_SIZE" >> "$GITHUB_OUTPUT"
# Truncate to ~80k chars to stay within API limits
if [ "$FULL_SIZE" -gt 80000 ]; then
head -c 80000 /tmp/pr-full.diff > /tmp/pr.diff
echo "truncated=true" >> "$GITHUB_OUTPUT"
else
cp /tmp/pr-full.diff /tmp/pr.diff
echo "truncated=false" >> "$GITHUB_OUTPUT"
fi
- name: Get PR info
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr view ${{ github.event.pull_request.number }} --json title,body > /tmp/pr-info.json
- name: Gather project context
run: |
# Read CLAUDE.md summary (first 100 lines)
if [ -f "CLAUDE.md" ]; then
head -100 CLAUDE.md > /tmp/project-context.txt
else
echo "No CLAUDE.md found." > /tmp/project-context.txt
fi
# List proposals
if [ -d "docs/03-development/proposals" ]; then
ls docs/03-development/proposals/ 2>/dev/null | head -20 > /tmp/proposals.txt
else
echo "No proposals directory." > /tmp/proposals.txt
fi
- name: Build API request
env:
TRUNCATED: ${{ steps.diff.outputs.truncated }}
DIFF_SIZE: ${{ steps.diff.outputs.diff_size }}
run: |
TRUNCATION_NOTE=""
if [ "$TRUNCATED" = "true" ]; then
TRUNCATION_NOTE="NOTE: The diff was truncated to 80k characters. Total size: ${DIFF_SIZE} bytes. Focus on what is visible."
fi
# Write the user prompt to a file (avoids shell variable limits)
cat > /tmp/user-prompt.txt <<PROMPT
Review this pull request.
PR Info:
$(cat /tmp/pr-info.json)
Project context:
$(cat /tmp/project-context.txt)
Proposals in repo:
$(cat /tmp/proposals.txt)
${TRUNCATION_NOTE}
Focus on:
1. Bugs, logic errors, race conditions, resource leaks
2. Error handling gaps
3. Security concerns (command injection, temp files, predictable paths)
4. Scope — flag if PR bundles unrelated changes
5. If proposals exist that match the PR topic, check alignment
6. Check if PR claims to fix already-fixed issues
Structure your review as: Critical Issues, Moderate Issues, Minor Issues, What Looks Good, Recommendation (approve/request changes).
Diff:
$(cat /tmp/pr.diff)
PROMPT
# Build JSON payload using jq with file input (no shell variable limits)
jq -n --rawfile prompt /tmp/user-prompt.txt '{
model: "openai/gpt-4.1",
messages: [
{
role: "system",
content: "You are a code reviewer for a Go CLI project (mxcli) that reads/modifies Mendix application projects. Key patterns: ANTLR4 grammar → AST → visitor → executor → BSON writer. Generated ANTLR parser files (mdl/grammar/parser/) are noise — note but skip. Review thoroughly but concisely."
},
{
role: "user",
content: $prompt
}
],
max_tokens: 4000
}' > /tmp/request.json
echo "Request payload size: $(wc -c < /tmp/request.json) bytes"
- name: Call GitHub Models API
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
HTTP_CODE=$(curl -s -w "%{http_code}" -o /tmp/response.json -X POST \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Content-Type: application/json" \
-d @/tmp/request.json \
https://models.github.ai/inference/chat/completions)
echo "HTTP status: $HTTP_CODE"
if [ "$HTTP_CODE" != "200" ]; then
echo "::warning::GitHub Models API returned HTTP $HTTP_CODE"
cat /tmp/response.json | head -c 1000
exit 0
fi
REVIEW=$(jq -r '.choices[0].message.content // empty' /tmp/response.json)
if [ -z "$REVIEW" ]; then
echo "::warning::AI review returned empty content. Response:"
cat /tmp/response.json | head -c 1000
exit 0
fi
# Save review for next step
echo "$REVIEW" > /tmp/review.txt
echo "Review generated ($(wc -c < /tmp/review.txt) bytes)"
- name: Post review comment
env:
GH_TOKEN: ${{ github.token }}
run: |
if [ ! -f /tmp/review.txt ]; then
echo "No review to post."
exit 0
fi
# Build comment body
{
echo "## AI Code Review"
echo ""
cat /tmp/review.txt
echo ""
echo "---"
echo "*Automated review by GitHub Models API (GPT-4.1) — [workflow source](${{ github.server_url }}/${{ github.repository }}/blob/main/.github/workflows/ai-review.yml)*"
} > /tmp/comment.md
gh pr comment ${{ github.event.pull_request.number }} --body-file /tmp/comment.md