265 lines
9.9 KiB
YAML
265 lines
9.9 KiB
YAML
# goose PR Reviewer
|
|
#
|
|
# Automated PR review using goose AI agent.
|
|
#
|
|
# Trigger: Comment "/goose [optional instructions]" on a PR (OWNER/MEMBER only)
|
|
#
|
|
# Examples:
|
|
# /goose
|
|
# /goose focus on security implications
|
|
# /goose check error handling in src/auth/
|
|
#
|
|
# Required Secrets:
|
|
# - ANTHROPIC_API_KEY: API key for Anthropic
|
|
#
|
|
# Optional Variables:
|
|
# - GOOSE_PROVIDER: LLM provider (default: anthropic)
|
|
# - GOOSE_MODEL: Model name (default: claude-opus-4-5)
|
|
#
|
|
# Security:
|
|
# - PR content could prompt-inject the agent; only trigger on PRs you trust.
|
|
# - Do not add workflow_dispatch: API calls fetch mutable data, enabling TOCTOU attacks.
|
|
|
|
name: goose PR Reviewer
|
|
|
|
on:
|
|
issue_comment:
|
|
types: [created]
|
|
|
|
env:
|
|
GOOSE_RECIPE: |
|
|
version: "1.0.0"
|
|
title: "Review Pull Request"
|
|
description: "Review PR #${PR_NUMBER}"
|
|
|
|
extensions:
|
|
- type: builtin
|
|
name: developer
|
|
- type: platform
|
|
name: todo
|
|
|
|
instructions: |
|
|
You are a code reviewer. Your job is to evaluate code, not implement changes.
|
|
|
|
Principles:
|
|
- Understand before you critique - explain the author's intent before finding fault
|
|
- Be constructive and specific in feedback
|
|
- Reference exact files and line numbers (format: path/file.rs:42)
|
|
- Verify claims with code evidence before stating them
|
|
- Respect project conventions (AGENTS.md)
|
|
- Never modify code - this is a read-only review
|
|
|
|
Issue Categories & Confidence Requirements:
|
|
- 🔴 BLOCKING: Must fix before merge. REQUIRES HIGH confidence with code evidence.
|
|
- 🟡 WARNING: Should fix (performance, conventions, missing tests). MEDIUM+ confidence.
|
|
- 🟢 SUGGESTION: Nice to have (style, refactoring). Can be speculative but label it.
|
|
- ✅ HIGHLIGHT: Good practices to acknowledge.
|
|
|
|
Anti-hallucination rules:
|
|
- Before claiming something is "missing", search for it with rg
|
|
- Before claiming UI/frontend changes are needed, trace the actual data flow
|
|
- If you cannot verify a claim, say "I couldn't verify this" not "this is wrong"
|
|
- 2 verified issues are better than 10 speculative ones
|
|
|
|
prompt: |
|
|
Review PR #${PR_NUMBER}: ${PR_TITLE}
|
|
|
|
The PR metadata is saved at /tmp/pr.json
|
|
The PR diff is saved at /tmp/pr.diff
|
|
|
|
The PR branch is already checked out. You are in the repository directory.
|
|
Use the codebase to understand context - explore with analyze, rg, and file reads.
|
|
|
|
Reviewer instructions from trigger:
|
|
${REVIEW_INSTRUCTIONS}
|
|
|
|
FIRST ACTION: Call todo_write with this entire checklist. Your memory degrades - the TODO is your only reliable memory. Update it frequently.
|
|
|
|
## PR Understanding
|
|
- Intent: [fill after Phase 1]
|
|
- Approach: [fill after Phase 1]
|
|
- Evaluation: [fill after Phase 2 - is this the right approach?]
|
|
|
|
## Phase 1: Understand
|
|
- [ ] Read /tmp/pr.json for PR description and context
|
|
- [ ] Read /tmp/pr.diff for the actual changes
|
|
- [ ] Read AGENTS.md if it exists
|
|
- [ ] Note reviewer instructions: ${REVIEW_INSTRUCTIONS}
|
|
- [ ] Summarize: What is this PR trying to accomplish?
|
|
|
|
## Phase 2: Evaluate (Empathize, then Challenge)
|
|
First, empathize with the author's choices:
|
|
- [ ] Trace the data/control flow through the changes
|
|
- [ ] Why did the author choose this approach?
|
|
- [ ] What constraints were they working under?
|
|
|
|
Then, challenge the approach:
|
|
- [ ] Architectural fit: Does this fit naturally, or is there awkward "pretending"?
|
|
- [ ] Alternatives: Could existing APIs/patterns be extended instead of adding new code?
|
|
- [ ] Consistency: Do names/types match similar code? Search with: rg "similar_name" --type rust
|
|
- [ ] Necessity: Is all this code needed? Could parameters/fields be removed?
|
|
- [ ] State and intent: If this enables/disables features, does it respect user preferences?
|
|
- [ ] Simpler path: Is there a way to achieve this with less code?
|
|
|
|
If fundamental design issues are found, note them and consider skipping detailed verification.
|
|
|
|
## Phase 3: Verify (only if approach is sound)
|
|
- [ ] Review for correctness and logic errors
|
|
- [ ] Check for security vulnerabilities
|
|
- [ ] Assess error handling
|
|
- [ ] Look for performance issues
|
|
- [ ] Verify edge cases are handled
|
|
- [ ] For each issue, add to Issues Found below with confidence level
|
|
|
|
Note: Do NOT run cargo check, cargo test, cargo fmt, or other build commands.
|
|
CI pipelines already validate those automatically. Focus on code review only.
|
|
|
|
## Phase 4: Report
|
|
- [ ] Prioritize findings: 🔴 Blocking > 🟡 Warning > 🟢 Suggestion
|
|
- [ ] Verify all 🔴 BLOCKING issues have HIGH confidence + code evidence
|
|
- [ ] Write review to /tmp/pr_review.md
|
|
- [ ] Be concise - quality over quantity
|
|
|
|
## Issues Found
|
|
[Add issues here as you find them, format: [HIGH/MED/LOW] [file:line] description - evidence]
|
|
|
|
---
|
|
|
|
Format your review in /tmp/pr_review.md as:
|
|
|
|
**Summary**: [1-2 sentence overview of what this PR does and your assessment]
|
|
|
|
Only include sections below if they have content. Omit empty sections entirely.
|
|
|
|
**🔴 Blocking Issues**
|
|
[Issues that must be fixed before merge. Each must have file:line and evidence.]
|
|
|
|
**🟡 Warnings**
|
|
[Issues that should be addressed]
|
|
|
|
**🟢 Suggestions**
|
|
[Optional improvements]
|
|
|
|
**✅ Highlights**
|
|
[Good practices observed in this PR]
|
|
|
|
---
|
|
*Review generated by goose*
|
|
|
|
Only write /tmp/pr_review.md when the review is complete.
|
|
Do NOT make any changes to the codebase.
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
|
|
concurrency:
|
|
group: goose-pr-review-${{ github.event.issue.number }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
review-pr:
|
|
if: |
|
|
github.event.issue.pull_request &&
|
|
startsWith(github.event.comment.body, '/goose') &&
|
|
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
|
|
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
|
|
container:
|
|
image: ghcr.io/block/goose:latest
|
|
options: --user root
|
|
env:
|
|
GOOSE_PROVIDER: ${{ vars.GOOSE_PROVIDER || 'anthropic' }}
|
|
GOOSE_MODEL: ${{ vars.GOOSE_MODEL || 'claude-opus-4-5' }}
|
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
HOME: /tmp/goose-home
|
|
|
|
steps:
|
|
- name: Acknowledge trigger
|
|
run: |
|
|
curl -sL -X POST \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
|
"https://api.github.com/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions" \
|
|
-d '{"content":"eyes"}'
|
|
|
|
- name: Checkout PR
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # pin@v4
|
|
with:
|
|
ref: refs/pull/${{ github.event.issue.number }}/head
|
|
fetch-depth: 1
|
|
|
|
- name: Install tools
|
|
run: |
|
|
apt-get update
|
|
apt-get install -y gettext curl ripgrep
|
|
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
|
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
|
apt-get update
|
|
apt-get install -y gh
|
|
|
|
- name: Get PR diff
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
gh pr diff ${{ github.event.issue.number }} --repo ${{ github.repository }} > /tmp/pr.diff
|
|
|
|
- name: Extract review instructions
|
|
id: instructions
|
|
env:
|
|
COMMENT_BODY: ${{ github.event.comment.body }}
|
|
run: |
|
|
if [ -n "$COMMENT_BODY" ]; then
|
|
INSTRUCTIONS=$(echo "$COMMENT_BODY" | sed 's|^/goose||' | sed 's|^[[:space:]]*||' | sed 's|[[:space:]]*$||')
|
|
fi
|
|
|
|
if [ -z "$INSTRUCTIONS" ]; then
|
|
INSTRUCTIONS="No specific instructions - perform a general code review."
|
|
fi
|
|
|
|
echo "instructions<<INSTRUCTIONS_EOF" >> $GITHUB_OUTPUT
|
|
echo "$INSTRUCTIONS" >> $GITHUB_OUTPUT
|
|
echo "INSTRUCTIONS_EOF" >> $GITHUB_OUTPUT
|
|
|
|
- name: Run goose review
|
|
id: goose
|
|
env:
|
|
PR_NUMBER: ${{ github.event.issue.number }}
|
|
PR_TITLE: ${{ github.event.issue.title }}
|
|
PR_BODY: ${{ github.event.issue.body }}
|
|
REVIEW_INSTRUCTIONS: ${{ steps.instructions.outputs.instructions }}
|
|
run: |
|
|
mkdir -p $HOME/.local/share/goose/sessions
|
|
mkdir -p $HOME/.config/goose
|
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
|
|
cat > /tmp/pr.json << 'PRJSON'
|
|
${{ toJson(github.event.issue) }}
|
|
PRJSON
|
|
|
|
echo "$GOOSE_RECIPE" | envsubst '$PR_NUMBER $PR_TITLE $PR_BODY $REVIEW_INSTRUCTIONS' > /tmp/recipe.yaml
|
|
|
|
goose run --recipe /tmp/recipe.yaml
|
|
|
|
if [ -f /tmp/pr_review.md ]; then
|
|
echo "has_review=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "has_review=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Post review comment
|
|
if: steps.goose.outputs.has_review == 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
gh pr comment ${{ github.event.issue.number }} --repo ${{ github.repository }} --body-file /tmp/pr_review.md
|
|
|
|
- name: Post failure comment
|
|
if: failure() || steps.goose.outputs.has_review != 'true'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
gh pr comment ${{ github.event.issue.number }} --repo ${{ github.repository }} --body "⚠️ goose PR review could not be completed. Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
|