name: '🧐 Qwen Pull Request Review' on: pull_request_target: types: ['opened'] pull_request_review_comment: types: ['created'] pull_request_review: types: ['submitted'] workflow_dispatch: inputs: pr_number: description: 'PR number to review' required: true type: 'number' jobs: review-pr: if: |- github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request_target' && github.event.action == 'opened' && (github.event.pull_request.author_association == 'OWNER' || github.event.pull_request.author_association == 'MEMBER' || github.event.pull_request.author_association == 'COLLABORATOR')) || (github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@qwen /review') && (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')) || (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@qwen /review') && (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@qwen /review') && (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'COLLABORATOR')) timeout-minutes: 15 runs-on: 'ubuntu-latest' permissions: contents: 'read' id-token: 'write' pull-requests: 'write' issues: 'write' steps: - name: 'Checkout PR code' uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5 with: token: '${{ secrets.GITHUB_TOKEN }}' fetch-depth: 0 - name: 'Get PR details (pull_request_target & workflow_dispatch)' id: 'get_pr' if: |- ${{ github.event_name == 'pull_request_target' || github.event_name == 'workflow_dispatch' }} env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' run: |- if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then PR_NUMBER=${{ github.event.inputs.pr_number }} else PR_NUMBER=${{ github.event.pull_request.number }} fi echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" # Get PR details PR_DATA=$(gh pr view $PR_NUMBER --json title,body,additions,deletions,changedFiles,baseRefName,headRefName) echo "pr_data=$PR_DATA" >> "$GITHUB_OUTPUT" # Get file changes CHANGED_FILES=$(gh pr diff $PR_NUMBER --name-only) echo "changed_files<> "$GITHUB_OUTPUT" echo "$CHANGED_FILES" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" - name: 'Get PR details (issue_comment)' id: 'get_pr_comment' if: |- ${{ github.event_name == 'issue_comment' }} env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' COMMENT_BODY: '${{ github.event.comment.body }}' run: |- PR_NUMBER=${{ github.event.issue.number }} echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" # Extract additional instructions from comment ADDITIONAL_INSTRUCTIONS=$(echo "$COMMENT_BODY" | sed 's/.*@qwen \/review//' | xargs) echo "additional_instructions=$ADDITIONAL_INSTRUCTIONS" >> "$GITHUB_OUTPUT" # Get PR details PR_DATA=$(gh pr view $PR_NUMBER --json title,body,additions,deletions,changedFiles,baseRefName,headRefName) echo "pr_data=$PR_DATA" >> "$GITHUB_OUTPUT" # Get file changes CHANGED_FILES=$(gh pr diff $PR_NUMBER --name-only) echo "changed_files<> "$GITHUB_OUTPUT" echo "$CHANGED_FILES" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" - name: 'Run Qwen PR Review' uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2' env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' PR_NUMBER: '${{ steps.get_pr.outputs.pr_number || steps.get_pr_comment.outputs.pr_number }}' PR_DATA: '${{ steps.get_pr.outputs.pr_data || steps.get_pr_comment.outputs.pr_data }}' CHANGED_FILES: '${{ steps.get_pr.outputs.changed_files || steps.get_pr_comment.outputs.changed_files }}' ADDITIONAL_INSTRUCTIONS: '${{ steps.get_pr.outputs.additional_instructions || steps.get_pr_comment.outputs.additional_instructions }}' REPOSITORY: '${{ github.repository }}' with: OPENAI_API_KEY: '${{ secrets.OPENAI_API_KEY }}' OPENAI_BASE_URL: '${{ secrets.OPENAI_BASE_URL }}' OPENAI_MODEL: '${{ secrets.OPENAI_MODEL }}' settings_json: |- { "coreTools": [ "run_shell_command", "write_file" ], "sandbox": false } prompt: |- You are an expert code reviewer. You have access to shell commands to gather PR information and perform the review. IMPORTANT: Use the available shell commands to gather information. Do not ask for information to be provided. Start by running these commands to gather the required data: 1. Run: echo "$PR_DATA" to get PR details (JSON format) 2. Run: echo "$CHANGED_FILES" to get the list of changed files 3. Run: echo "$PR_NUMBER" to get the PR number 4. Run: echo "$ADDITIONAL_INSTRUCTIONS" to see any specific review instructions from the user 5. Run: gh pr diff $PR_NUMBER to see the full diff 6. For any specific files, use: cat filename, head -50 filename, or tail -50 filename Additional Review Instructions: If ADDITIONAL_INSTRUCTIONS contains text, prioritize those specific areas or focus points in your review. Common instruction examples: "focus on security", "check performance", "review error handling", "check for breaking changes" Once you have the information, provide a comprehensive code review by: 1. Writing your review to a file: write_file("review.md", "") 2. Posting the review: gh pr comment $PR_NUMBER --body-file review.md --repo $REPOSITORY Review Areas: - **Security**: Authentication, authorization, input validation, data sanitization - **Performance**: Algorithms, database queries, caching, resource usage - **Reliability**: Error handling, logging, testing coverage, edge cases - **Maintainability**: Code structure, documentation, naming conventions - **Functionality**: Logic correctness, requirements fulfillment Output Format: Structure your review using this exact format with markdown: ## 📋 Review Summary Provide a brief 2-3 sentence overview of the PR and overall assessment. ## 🔍 General Feedback - List general observations about code quality - Mention overall patterns or architectural decisions - Highlight positive aspects of the implementation - Note any recurring themes across files ## 🎯 Specific Feedback Only include sections below that have actual issues. If there are no issues in a priority category, omit that entire section. ### 🔴 Critical (Only include this section if there are critical issues) Issues that must be addressed before merging (security vulnerabilities, breaking changes, major bugs): - **File: `filename:line`** - Description of critical issue with specific recommendation ### 🟡 High (Only include this section if there are high priority issues) Important issues that should be addressed (performance problems, design flaws, significant bugs): - **File: `filename:line`** - Description of high priority issue with suggested fix ### 🟢 Medium (Only include this section if there are medium priority issues) Improvements that would enhance code quality (style issues, minor optimizations, better practices): - **File: `filename:line`** - Description of medium priority improvement ### 🔵 Low (Only include this section if there are suggestions) Nice-to-have improvements and suggestions (documentation, naming, minor refactoring): - **File: `filename:line`** - Description of suggestion or enhancement **Note**: If no specific issues are found in any category, simply state "No specific issues identified in this review." ## ✅ Highlights (Only include this section if there are positive aspects to highlight) - Mention specific good practices or implementations - Acknowledge well-written code sections - Note improvements from previous versions