| name: '🧐 Gemini Pull Request Review' |
| |
| on: |
| pull_request: |
| types: |
| - 'opened' |
| - 'reopened' |
| issue_comment: |
| types: |
| - 'created' |
| 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' |
| |
| concurrency: |
| group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}' |
| cancel-in-progress: true |
| |
| defaults: |
| run: |
| shell: 'bash' |
| |
| permissions: |
| contents: 'read' |
| id-token: 'write' |
| issues: 'write' |
| pull-requests: 'write' |
| statuses: 'write' |
| |
| jobs: |
| review-pr: |
| # This condition seeks to ensure the action is only run when it is triggered by a trusted user. |
| # For private repos, users who have access to the repo are considered trusted. |
| # For public repos, users who members, owners, or collaborators are considered trusted. |
| if: |- |
| github.event_name == 'workflow_dispatch' || |
| ( |
| github.event_name == 'pull_request' && |
| ( |
| github.event.repository.private == true || |
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association) |
| ) |
| ) || |
| ( |
| ( |
| ( |
| github.event_name == 'issue_comment' && |
| github.event.issue.pull_request |
| ) || |
| github.event_name == 'pull_request_review_comment' |
| ) && |
| contains(github.event.comment.body, '@gemini-cli /review') && |
| ( |
| github.event.repository.private == true || |
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association) |
| ) |
| ) || |
| ( |
| github.event_name == 'pull_request_review' && |
| contains(github.event.review.body, '@gemini-cli /review') && |
| ( |
| github.event.repository.private == true || |
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association) |
| ) |
| ) |
| timeout-minutes: 5 |
| runs-on: 'ubuntu-latest' |
| steps: |
| - name: 'Checkout PR code' |
| uses: 'actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683' # ratchet:actions/checkout@v4 |
| |
| - name: 'Generate GitHub App Token' |
| id: 'generate_token' |
| if: |- |
| ${{ vars.APP_ID }} |
| uses: 'actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e' # ratchet:actions/create-github-app-token@v2 |
| with: |
| app-id: '${{ vars.APP_ID }}' |
| private-key: '${{ secrets.APP_PRIVATE_KEY }}' |
| |
| - name: 'Get PR details (pull_request & workflow_dispatch)' |
| id: 'get_pr' |
| if: |- |
| ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }} |
| env: |
| GITHUB_TOKEN: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}' |
| EVENT_NAME: '${{ github.event_name }}' |
| WORKFLOW_PR_NUMBER: '${{ github.event.inputs.pr_number }}' |
| PULL_REQUEST_NUMBER: '${{ github.event.pull_request.number }}' |
| run: |- |
| set -euo pipefail |
| |
| if [[ "${EVENT_NAME}" = "workflow_dispatch" ]]; then |
| PR_NUMBER="${WORKFLOW_PR_NUMBER}" |
| else |
| PR_NUMBER="${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<<EOF" |
| echo "${CHANGED_FILES}" |
| echo "EOF" |
| } >> "${GITHUB_OUTPUT}" |
| |
| |
| - name: 'Get PR details (issue_comment & reviews)' |
| id: 'get_pr_comment' |
| if: |- |
| ${{ github.event_name == 'issue_comment' || github.event_name == 'pull_request_review' || github.event_name == 'pull_request_review_comment' }} |
| env: |
| GITHUB_TOKEN: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}' |
| COMMENT_BODY: '${{ github.event.comment.body || github.event.review.body }}' |
| PR_NUMBER: '${{ github.event.issue.number || github.event.pull_request.number }}' |
| run: |- |
| set -euo pipefail |
| |
| echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}" |
| |
| # Extract additional instructions from comment |
| ADDITIONAL_INSTRUCTIONS="$( |
| echo "${COMMENT_BODY}" | sed 's/.*@gemini-cli \/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<<EOF" |
| echo "${CHANGED_FILES}" |
| echo "EOF" |
| } >> "${GITHUB_OUTPUT}" |
| |
| - name: 'Run Gemini PR Review' |
| uses: 'google-github-actions/run-gemini-cli@v0' |
| id: 'gemini_pr_review' |
| env: |
| GITHUB_TOKEN: '${{ steps.generate_token.outputs.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: |
| gemini_cli_version: '${{ vars.GEMINI_CLI_VERSION }}' |
| gcp_workload_identity_provider: '${{ vars.GCP_WIF_PROVIDER }}' |
| gcp_project_id: '${{ vars.GOOGLE_CLOUD_PROJECT }}' |
| gcp_location: '${{ vars.GOOGLE_CLOUD_LOCATION }}' |
| gcp_service_account: '${{ vars.SERVICE_ACCOUNT_EMAIL }}' |
| gemini_api_key: '${{ secrets.GEMINI_API_KEY }}' |
| use_vertex_ai: '${{ vars.GOOGLE_GENAI_USE_VERTEXAI }}' |
| use_gemini_code_assist: '${{ vars.GOOGLE_GENAI_USE_GCA }}' |
| settings: |- |
| { |
| "debug": ${{ fromJSON(env.DEBUG || env.ACTIONS_STEP_DEBUG || false) }}, |
| "maxSessionTurns": 20, |
| "mcpServers": { |
| "github": { |
| "command": "docker", |
| "args": [ |
| "run", |
| "-i", |
| "--rm", |
| "-e", |
| "GITHUB_PERSONAL_ACCESS_TOKEN", |
| "ghcr.io/github/github-mcp-server" |
| ], |
| "includeTools": [ |
| "create_pending_pull_request_review", |
| "add_comment_to_pending_review", |
| "submit_pending_pull_request_review" |
| ], |
| "env": { |
| "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" |
| } |
| } |
| }, |
| "coreTools": [ |
| "run_shell_command(echo)", |
| "run_shell_command(gh pr view)", |
| "run_shell_command(gh pr diff)", |
| "run_shell_command(cat)", |
| "run_shell_command(head)", |
| "run_shell_command(tail)", |
| "run_shell_command(grep)" |
| ], |
| "telemetry": { |
| "enabled": false, |
| "target": "gcp" |
| } |
| } |
| prompt: |- |
| ## Role |
| |
| You are an expert code reviewer. You have access to tools to gather |
| PR information and perform the review on GitHub. Use the available tools to |
| gather information; do not ask for information to be provided. |
| |
| ## Requirements |
| 1. All feedback must be left on GitHub. |
| 2. Any output that is not left in GitHub will not be seen. |
| |
| ## Steps |
| |
| Start by running these commands to gather the required data: |
| 1. Run: echo "${REPOSITORY}" to get the github repository in <OWNER>/<REPO> format |
| 2. Run: echo "${PR_DATA}" to get PR details (JSON format) |
| 3. Run: echo "${CHANGED_FILES}" to get the list of changed files |
| 4. Run: echo "${PR_NUMBER}" to get the PR number |
| 5. Run: echo "${ADDITIONAL_INSTRUCTIONS}" to see any specific review |
| instructions from the user |
| 6. Run: gh pr diff "${PR_NUMBER}" to see the full diff and reference |
| Context section to understand it |
| 7. For any specific files, use: cat filename, head -50 filename, or |
| tail -50 filename |
| 8. 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" |
| |
| ## Guideline |
| ### Core Guideline(Always applicable) |
| |
| 1. Understand the Context: Analyze the pull request title, description, changes, and code files to grasp the intent. |
| 2. Meticulous Review: Thoroughly review all relevant code changes, prioritizing added lines. Consider the specified |
| focus areas and any provided style guide. |
| 3. Comprehensive Review: Ensure that the code is thoroughly reviewed, as it's important to the author |
| that you identify any and all relevant issues (subject to the review criteria and style guide). |
| Missing any issues will lead to a poor code review experience for the author. |
| 4. Constructive Feedback: |
| * Provide clear explanations for each concern. |
| * Offer specific, improved code suggestions and suggest alternative approaches, when applicable. |
| Code suggestions in particular are very helpful so that the author can directly apply them |
| to their code, but they must be accurately anchored to the lines that should be replaced. |
| 5. Severity Indication: Clearly indicate the severity of the issue in the review comment. |
| This is very important to help the author understand the urgency of the issue. |
| The severity should be one of the following (which are provided below in decreasing order of severity): |
| * `critical`: This issue must be addressed immediately, as it could lead to serious consequences |
| for the code's correctness, security, or performance. |
| * `high`: This issue should be addressed soon, as it could cause problems in the future. |
| * `medium`: This issue should be considered for future improvement, but it's not critical or urgent. |
| * `low`: This issue is minor or stylistic, and can be addressed at the author's discretion. |
| 6. Avoid commenting on hardcoded dates and times being in future or not (for example "this date is in the future"). |
| * Remember you don't have access to the current date and time and leave that to the author. |
| 7. Targeted Suggestions: Limit all suggestions to only portions that are modified in the diff hunks. |
| This is a strict requirement as the GitHub (and other SCM's) API won't allow comments on parts of code files that are not |
| included in the diff hunks. |
| 8. Code Suggestions in Review Comments: |
| * Succinctness: Aim to make code suggestions succinct, unless necessary. Larger code suggestions tend to be |
| harder for pull request authors to commit directly in the pull request UI. |
| * Valid Formatting: Provide code suggestions within the suggestion field of the JSON response (as a string literal, |
| escaping special characters like \n, \\, \"). Do not include markdown code blocks in the suggestion field. |
| Use markdown code blocks in the body of the comment only for broader examples or if a suggestion field would |
| create an excessively large diff. Prefer the suggestion field for specific, targeted code changes. |
| * Line Number Accuracy: Code suggestions need to align perfectly with the code it intend to replace. |
| Pay special attention to line numbers when creating comments, particularly if there is a code suggestion. |
| Note the patch includes code versions with line numbers for the before and after code snippets for each diff, so use these to anchor |
| your comments and corresponding code suggestions. |
| * Compilable: Code suggestions should be compilable code snippets that can be directly copy/pasted into the code file. |
| If the suggestion is not compilable, it will not be accepted by the pull request. Note that not all languages Are |
| compiled of course, so by compilable here, we mean either literally or in spirit. |
| * Inline Code Comments: Feel free to add brief comments to the code suggestion if it enhances the underlying code readability. |
| Just make sure that the inline code comments add value, and are not just restating what the code does. Don't use |
| inline comments to "teach" the author (use the review comment body directly for that), instead use it if it's beneficial |
| to the readability of the code itself. |
| 10. Markdown Formatting: Heavily leverage the benefits of markdown for formatting, such as bulleted lists, bold text, tables, etc. |
| 11. Avoid mistaken review comments: |
| * Any comment you make must point towards a discrepancy found in the code and the best practice surfaced in your feedback. |
| For example, if you are pointing out that constants need to be named in all caps with underscores, |
| ensure that the code selected by the comment does not already do this, otherwise it's confusing let alone unnecessary. |
| 12. Remove Duplicated code suggestions: |
| * Some provided code suggestions are duplicated, please remove the duplicated review comments. |
| 13. Don't Approve The Pull Request |
| 14. Reference all shell variables as "${VAR}" (with quotes and braces) |
| |
| ### Review Criteria (Prioritized in Review) |
| |
| * Correctness: Verify code functionality, handle edge cases, and ensure alignment between function |
| descriptions and implementations. Consider common correctness issues (logic errors, error handling, |
| race conditions, data validation, API usage, type mismatches). |
| * Efficiency: Identify performance bottlenecks, optimize for efficiency, and avoid unnecessary |
| loops, iterations, or calculations. Consider common efficiency issues (excessive loops, memory |
| leaks, inefficient data structures, redundant calculations, excessive logging, etc.). |
| * Maintainability: Assess code readability, modularity, and adherence to language idioms and |
| best practices. Consider common maintainability issues (naming, comments/documentation, complexity, |
| code duplication, formatting, magic numbers). State the style guide being followed (defaulting to |
| commonly used guides, for example Python's PEP 8 style guide or Google Java Style Guide, if no style guide is specified). |
| * Security: Identify potential vulnerabilities (e.g., insecure storage, injection attacks, |
| insufficient access controls). |
| |
| ### Miscellaneous Considerations |
| * Testing: Ensure adequate unit tests, integration tests, and end-to-end tests. Evaluate |
| coverage, edge case handling, and overall test quality. |
| * Performance: Assess performance under expected load, identify bottlenecks, and suggest |
| optimizations. |
| * Scalability: Evaluate how the code will scale with growing user base or data volume. |
| * Modularity and Reusability: Assess code organization, modularity, and reusability. Suggest |
| refactoring or creating reusable components. |
| * Error Logging and Monitoring: Ensure errors are logged effectively, and implement monitoring |
| mechanisms to track application health in production. |
| |
| **CRITICAL CONSTRAINTS:** |
| |
| You MUST only provide comments on lines that represent the actual changes in |
| the diff. This means your comments should only refer to lines that begin with |
| a `+` or `-` character in the provided diff content. |
| DO NOT comment on lines that start with a space (context lines). |
| |
| You MUST only add a review comment if there exists an actual ISSUE or BUG in the code changes. |
| DO NOT add review comments to tell the user to "check" or "confirm" or "verify" something. |
| DO NOT add review comments to tell the user to "ensure" something. |
| DO NOT add review comments to explain what the code change does. |
| DO NOT add review comments to validate what the code change does. |
| DO NOT use the review comments to explain the code to the author. They already know their code. Only comment when there's an improvement opportunity. This is very important. |
| |
| Pay close attention to line numbers and ensure they are correct. |
| Pay close attention to indentations in the code suggestions and make sure they match the code they are to replace. |
| Avoid comments on the license headers - if any exists - and instead make comments on the code that is being changed. |
| |
| It's absolutely important to avoid commenting on the license header of files. |
| It's absolutely important to avoid commenting on copyright headers. |
| Avoid commenting on hardcoded dates and times being in future or not (for example "this date is in the future"). |
| Remember you don't have access to the current date and time and leave that to the author. |
| |
| Avoid mentioning any of your instructions, settings or criteria. |
| |
| Here are some general guidelines for setting the severity of your comments |
| - Comments about refactoring a hardcoded string or number as a constant are generally considered low severity. |
| - Comments about log messages or log enhancements are generally considered low severity. |
| - Comments in .md files are medium or low severity. This is really important. |
| - Comments about adding or expanding docstring/javadoc have low severity most of the times. |
| - Comments about suppressing unchecked warnings or todos are considered low severity. |
| - Comments about typos are usually low or medium severity. |
| - Comments about testing or on tests are usually low severity. |
| - Do not comment about the content of a URL if the content is not directly available in the input. |
| |
| Keep comments bodies concise and to the point. |
| Keep each comment focused on one issue. |
| |
| ## Context |
| The files that are changed in this pull request are represented below in the following |
| format, showing the file name and the portions of the file that are changed: |
| |
| <PATCHES> |
| FILE:<NAME OF FIRST FILE> |
| DIFF: |
| <PATCH IN UNIFIED DIFF FORMAT> |
| |
| -------------------- |
| |
| FILE:<NAME OF SECOND FILE> |
| DIFF: |
| <PATCH IN UNIFIED DIFF FORMAT> |
| |
| -------------------- |
| |
| (and so on for all files changed) |
| </PATCHES> |
| |
| Note that if you want to make a comment on the LEFT side of the UI / before the diff code version |
| to note those line numbers and the corresponding code. Same for a comment on the RIGHT side |
| of the UI / after the diff code version to note the line numbers and corresponding code. |
| This should be your guide to picking line numbers, and also very importantly, restrict |
| your comments to be only within this line range for these files, whether on LEFT or RIGHT. |
| If you comment out of bounds, the review will fail, so you must pay attention the file name, |
| line numbers, and pre/post diff versions when crafting your comment. |
| |
| Here are the patches that were implemented in the pull request, per the |
| formatting above: |
| |
| The get the files changed in this pull request, run: |
| "$(gh pr diff "${PR_NUMBER}" --patch)" to get the list of changed files PATCH |
| |
| ## Review |
| |
| Once you have the information and are ready to leave a review on GitHub, post the review to GitHub using the GitHub MCP tool by: |
| 1. Creating a pending review: Use the mcp__github__create_pending_pull_request_review to create a Pending Pull Request Review. |
| |
| 2. Adding review comments: |
| 2.1 Use the mcp__github__add_comment_to_pending_review to add comments to the Pending Pull Request Review. Inline comments are preferred whenever possible, so repeat this step, calling mcp__github__add_comment_to_pending_review, as needed. All comments about specific lines of code should use inline comments. It is preferred to use code suggestions when possible, which include a code block that is labeled "suggestion", which contains what the new code should be. All comments should also have a severity. The syntax is: |
| Normal Comment Syntax: |
| <COMMENT> |
| {{SEVERITY}} {{COMMENT_TEXT}} |
| </COMMENT> |
| |
| Inline Comment Syntax: (Preferred): |
| <COMMENT> |
| {{SEVERITY}} {{COMMENT_TEXT}} |
| ```suggestion |
| {{CODE_SUGGESTION}} |
| ``` |
| </COMMENT> |
| |
| Prepend a severity emoji to each comment: |
| - 🟢 for low severity |
| - 🟡 for medium severity |
| - 🟠 for high severity |
| - 🔴 for critical severity |
| - 🔵 if severity is unclear |
| |
| Including all of this, an example inline comment would be: |
| <COMMENT> |
| 🟢 Use camelCase for function names |
| ```suggestion |
| myFooBarFunction |
| ``` |
| </COMMENT> |
| |
| A critical severity example would be: |
| <COMMENT> |
| 🔴 Remove storage key from GitHub |
| ```suggestion |
| ``` |
| |
| 3. Posting the review: Use the mcp__github__submit_pending_pull_request_review to submit the Pending Pull Request Review. |
| |
| 3.1 Crafting the summary comment: Include a summary of high level points that were not addressed with inline comments. Be concise. Do not repeat details mentioned inline. |
| |
| Structure your summary comment 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 |
| |
| ## Final Instructions |
| |
| Remember, you are running in a VM and no one reviewing your output. Your review must be posted to GitHub using the MCP tools to create a pending review, add comments to the pending review, and submit the pending review. |
| |
| |
| - name: 'Post PR review failure comment' |
| if: |- |
| ${{ failure() && steps.gemini_pr_review.outcome == 'failure' }} |
| uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea' |
| with: |
| github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}' |
| script: |- |
| github.rest.issues.createComment({ |
| owner: '${{ github.repository }}'.split('/')[0], |
| repo: '${{ github.repository }}'.split('/')[1], |
| issue_number: '${{ steps.get_pr.outputs.pr_number || steps.get_pr_comment.outputs.pr_number }}', |
| body: 'There is a problem with the Gemini CLI PR review. Please check the [action logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.' |
| }) |