diff --git a/.github/workflows/ampcode-pr-review.yml b/.github/workflows/ampcode-pr-review.yml new file mode 100644 index 000000000..6c100c243 --- /dev/null +++ b/.github/workflows/ampcode-pr-review.yml @@ -0,0 +1,133 @@ +name: Ampcode PR Review + +on: + pull_request: + types: [opened, ready_for_review, synchronize] + branches: [main, staging] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + ampcode-review: + if: github.event.pull_request.draft == false + timeout-minutes: 15 + runs-on: ubuntu-latest + strategy: + matrix: + review-chunk: [1] + max-parallel: 3 + + steps: + - name: Checkout PR branch + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install Ampcode CLI + run: | + npm install -g @sourcegraph/amp + amp --version + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Install project dependencies + run: pnpm install --frozen-lockfile + + - name: Get changed files + id: changed-files + run: | + git fetch origin ${{ github.event.pull_request.base.ref }} + CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }}..HEAD | grep -E '\.(ts|tsx|js|jsx|py|go|java|cpp|c|h|hpp|rs|rb|php|cs|swift|kt|scala|clj|hs|ml|fs|elm|dart|lua|r|sql|sh|bash|zsh|fish|ps1|bat|cmd|yaml|yml|json|toml|ini|cfg|conf|xml|html|css|scss|sass|less|styl|vue|svelte|astro|md|mdx|tex|latex|bib|org|rst|adoc|asciidoc|wiki|txt)$' | head -50 || echo "") + echo "changed_files<> $GITHUB_OUTPUT + echo "$CHANGED_FILES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "Changed files count: $(echo "$CHANGED_FILES" | wc -l)" + + - name: Run Ampcode Review + if: steps.changed-files.outputs.changed_files != '' + env: + AMP_API_KEY: ${{ secrets.AMPCODE_API_KEY }} + run: | + echo "Running ampcode review on changed files..." + + # Create a temporary file with the changed files list + echo "${{ steps.changed-files.outputs.changed_files }}" > changed_files.txt + + # Run ampcode review on the changed files + REVIEW_OUTPUT=$(amp -x "Review the following files for code quality, potential bugs, security issues, performance concerns, and best practices. Focus on providing specific, actionable feedback with line numbers when possible. Files to review: $(cat changed_files.txt | tr '\n' ' ')" 2>&1 || echo "Ampcode review failed") + + # Save review output to file + echo "$REVIEW_OUTPUT" > ampcode_review.txt + + # Display review output for debugging + echo "=== Ampcode Review Output ===" + cat ampcode_review.txt + echo "=== End Review Output ===" + + - name: Parse and Post Review Comments + if: steps.changed-files.outputs.changed_files != '' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Check if review output exists and is not empty + if [ ! -f ampcode_review.txt ] || [ ! -s ampcode_review.txt ]; then + echo "No review output found or file is empty" + exit 0 + fi + + # Read the review output + REVIEW_CONTENT=$(cat ampcode_review.txt) + + # Sanitize the review content to prevent injection attacks + SANITIZED_CONTENT=$(echo "$REVIEW_CONTENT" | sed 's/"/\\"/g' | sed 's/`/\\`/g' | sed 's/\$/\\$/g' | tr '\n' ' ') + + # Create a comprehensive PR review comment with sanitized content + cat > review_comment.json << EOF + { + "body": "## 🤖 Automated Code Review by Ampcode\n\n**Review Summary:**\n\nI've analyzed the changes in this PR using AI-powered code review. Here are my findings:\n\n### 📋 Review Results\n\n\`\`\`\n${SANITIZED_CONTENT}\n\`\`\`\n\n### 🔍 Key Areas Reviewed\n- Code quality and best practices\n- Potential bugs and security issues\n- Performance considerations\n- Maintainability and readability\n\n### 📝 Notes\n- This is an automated review generated by Ampcode AI\n- Please review the suggestions and apply them as appropriate\n- For questions about specific recommendations, feel free to ask!\n\n---\n*Generated by [Ampcode](https://ampcode.com) • [View Workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})*", + "event": "COMMENT" + } + EOF + + # Post the review comment + curl -X POST \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Content-Type: application/json" \ + -d @review_comment.json \ + "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews" + + echo "Review comment posted successfully" + + - name: Cleanup + if: always() + run: | + # Clean up temporary files + rm -f changed_files.txt ampcode_review.txt review_comment.json + echo "Cleanup completed" + + - name: Summary + if: always() + run: | + echo "=== Ampcode PR Review Summary ===" + echo "PR Number: ${{ github.event.pull_request.number }}" + echo "PR Title: ${{ github.event.pull_request.title }}" + echo "Base Branch: ${{ github.event.pull_request.base.ref }}" + echo "Head Branch: ${{ github.event.pull_request.head.ref }}" + echo "Changed Files: $(echo '${{ steps.changed-files.outputs.changed_files }}' | wc -l)" + echo "Review Status: $([ -f ampcode_review.txt ] && echo 'Completed' || echo 'Skipped')" + echo "=== End Summary ==="