Skip to content

dev-inf: add GitHub Actions workflows for issue auto-solving #4

dev-inf: add GitHub Actions workflows for issue auto-solving

dev-inf: add GitHub Actions workflows for issue auto-solving #4

name: PR Comment Addresser
on:
pull_request_review_comment:
types: [created]
concurrency:
group: autosolve-pr-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
address-review-comments:
runs-on: ubuntu-latest
timeout-minutes: 60
# Only trigger for:
# - PRs with 'o-autosolver' label
# - Comments NOT from the bot itself
# - Comments NOT containing our response marker (prevents loops)
if: |
contains(github.event.pull_request.labels.*.name, 'o-autosolver') &&
github.actor != 'github-actions[bot]' &&
github.actor != 'crdb-autosolver' &&
!contains(github.event.comment.body, '[autosolve-response]')
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- name: Checkout PR branch from fork
uses: actions/checkout@v5
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
token: ${{ secrets.AUTOSOLVER_PAT }}
- name: Authenticate to Google Cloud
uses: 'google-github-actions/auth@v3'
with:
project_id: 'vertex-model-runners'
service_account: '[email protected]'
workload_identity_provider: 'projects/72497726731/locations/global/workloadIdentityPools/ai-review/providers/ai-review'
- name: Fetch all review comments
id: fetch_comments
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Get all review comments on this PR
COMMENTS=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments)
{
echo 'comments<<EOF'
echo "$COMMENTS"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Address review comments
id: address
uses: cockroachdb/claude-code-action@v1
env:
ANTHROPIC_VERTEX_PROJECT_ID: vertex-model-runners
CLOUD_ML_REGION: us-east5
# Pass user-controlled content via env vars to prevent prompt injection
COMMENT_USER: ${{ github.event.comment.user.login }}
COMMENT_PATH: ${{ github.event.comment.path }}
COMMENT_LINE: ${{ github.event.comment.line }}
COMMENT_BODY: ${{ github.event.comment.body }}
ALL_COMMENTS: ${{ steps.fetch_comments.outputs.comments }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
use_vertex: "true"
claude_args: |
--model claude-opus-4-5@20251101
--allowedTools "Read,Write,Edit,Grep,Glob,Bash(./dev test:*),Bash(./dev testlogic:*),Bash(./dev build:*),Bash(./dev generate:*),Bash(git:*)"
prompt: |
PR #${{ github.event.pull_request.number }} has received review comments.
The review comment details are provided in environment variables:
- COMMENT_USER: The username of the commenter
- COMMENT_PATH: The file path the comment is on
- COMMENT_LINE: The line number
- COMMENT_BODY: The comment text
- ALL_COMMENTS: JSON array of all review comments on this PR
Instructions:
1. Read CLAUDE.md for project conventions
2. Read the environment variables to understand the review feedback
3. Address the review feedback by making code changes
4. Run relevant tests to verify changes
5. Stage all changes with git add
When formatting commits, follow the guidelines in CLAUDE.md.
Respond with a concise summary of changes made to address each comment.
- name: Extract Claude Result
id: claude_result
if: steps.address.conclusion == 'success'
run: |
if [ ! -f "${{ steps.address.outputs.execution_file }}" ]; then
echo "::error::Execution file not found: ${{ steps.address.outputs.execution_file }}"
exit 1
fi
RESULT=$(jq -r '.[] | select(.type == "result") | .result' "${{ steps.address.outputs.execution_file }}") || {
echo "::error::Failed to parse execution file with jq"
exit 1
}
if [ -z "$RESULT" ]; then
echo "::error::No result found in execution file"
exit 1
fi
{
echo 'result<<EOF'
echo "$RESULT"
echo 'EOF'
} >> "$GITHUB_OUTPUT"
- name: Commit and push changes
id: commit
env:
AUTOSOLVER_PAT: ${{ secrets.AUTOSOLVER_PAT }}
run: |
git config user.name "crdb-autosolver"
git config user.email "[email protected]"
# Check if there are staged changes (Claude should have staged them)
# If no staged changes, also check for unstaged changes that need staging
if git diff --quiet --cached; then
# No staged changes - check if Claude made changes but forgot to stage
if ! git diff --quiet; then
echo "::warning::Changes detected but not staged. Staging all changes."
git add -A
else
echo "No staged changes to commit"
echo "pushed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
fi
# Check authorship before amending - only amend if we authored the commit
AUTHOR_EMAIL=$(git log -1 --format='%ae')
if [ "$AUTHOR_EMAIL" = "[email protected]" ]; then
# Check if staged changes differ from HEAD before amending
if git diff --cached --quiet HEAD; then
echo "Staged changes are identical to HEAD, nothing to amend"
echo "pushed=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# Amend the existing commit with the new changes
git commit --amend --no-edit
else
# Create a new commit if we didn't author the original
git commit -m "Address review comments
Generated by Claude Code Auto-Solver

Check failure on line 159 in .github/workflows/pr-autosolve-comments.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/pr-autosolve-comments.yml

Invalid workflow file

You have an error in your yaml syntax on line 159
Co-Authored-By: Claude <[email protected]>"
fi
# Force push to the fork
# NOTE: This is safe because this workflow only runs on PRs with 'o-autosolver' label,
# which are bot-owned branches. We never force push to branches owned by humans.
git push --force origin ${{ github.event.pull_request.head.ref }}
echo "pushed=true" >> "$GITHUB_OUTPUT"
- name: Post summary comment
if: steps.commit.outputs.pushed == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Create comment with marker to prevent infinite loops
gh pr comment ${{ github.event.pull_request.number }} --body "[autosolve-response]
I've addressed the review comments and pushed updates.
**Changes made:**
${{ steps.claude_result.outputs.result }}
Please review the updated code."
- name: Post no-changes comment
if: steps.commit.outputs.pushed == 'false' && steps.address.conclusion == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr comment ${{ github.event.pull_request.number }} --body "[autosolve-response]
I reviewed the comments but no code changes were necessary.
**Analysis:**
${{ steps.claude_result.outputs.result }}"