Testing Gemini CLI GitHub Actions Authentication on Google Cloud for Automating PR Reviews

Testing Gemini CLI GitHub Actions Authentication on Google Cloud for Automating PR Reviews

2025.08.26

I am from the Data Business Division.

Recently, Gemini CLI GitHub Actions has been released as a preview.
This makes it easy to automate tasks such as issue triage and code review by calling Gemini CLI from GitHub Actions.

https://cloud.google.com/blog/ja/topics/developers-practitioners/introducing-gemini-cli-github-actions

In this article, I would like to try having a Pull Request (PR) reviewed using Gemini CLI with Vertex AI as the backend, authenticated from GitHub Actions to Google Cloud using Workload Identity Federation (WIF).

https://github.com/google-github-actions/run-gemini-cli

Setup Method

Let's proceed with the setup right away.
To use this workflow, you need to authenticate with both Google (Gemini API or Google Cloud) and GitHub.
For an overview of the authentication methods, please refer to the following document.

https://github.com/google-github-actions/run-gemini-cli/blob/main/docs/authentication.md## Google Cloud Authentication

First, we will perform authentication with Google.
In this case, we will use keyless authentication to Google Cloud with WIF (Workload Identity Federation) via GitHub Actions OIDC, and use Vertex AI as the backend for Gemini CLI.

Run the following script to create the resources needed for authentication and grant permissions. The main steps are as follows:

  1. Creating a Workload Identity Pool
  2. Creating a Workload Identity Provider (GitHub OIDC)
  3. Creating a service account to be impersonated
  4. Granting necessary permissions
  5. Adding to GitHub repository variables
			
			#!/bin/bash

## Change as needed
export GOOGLE_CLOUD_PROJECT=""
export GOOGLE_CLOUD_LOCATION="global"
export WORKLOAD_IDENTITY_POOL="gemini-cli-pool"
export WORKLOAD_IDENTITY_PROVIDER="github"
export GITHUB_REPO="yuya-hanzawa/try-run-gemini-cli"
export SA_ID="gemini-cli"
export SA_EMAIL="${SA_ID}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"

## 1. Create Workload Identity Pool
gcloud iam workload-identity-pools create "${WORKLOAD_IDENTITY_POOL}" \
    --project="${GOOGLE_CLOUD_PROJECT}" \
    --location="${GOOGLE_CLOUD_LOCATION}"

## 2. Create Workload Identity Provider
gcloud iam workload-identity-pools providers create-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
    --project="${GOOGLE_CLOUD_PROJECT}" \
    --location="${GOOGLE_CLOUD_LOCATION}" \
    --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
    --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \
    --attribute-condition="assertion.repository == '${GITHUB_REPO}'" \
    --issuer-uri="https://token.actions.githubusercontent.com"

WIF_POOL_ID=$(gcloud iam workload-identity-pools describe "${WORKLOAD_IDENTITY_POOL}" \
    --project="${GOOGLE_CLOUD_PROJECT}" \
    --location="${GOOGLE_CLOUD_LOCATION}" \
    --format="value(name)")

PRINCIPAL_SET="principalSet://iam.googleapis.com/${WIF_POOL_ID}/attribute.repository/${GITHUB_REPO}"

WIF_PROVIDER_FULL=$(gcloud iam workload-identity-pools providers describe "${WORKLOAD_IDENTITY_PROVIDER}" \
    --project="${GOOGLE_CLOUD_PROJECT}" \
    --location="${GOOGLE_CLOUD_LOCATION}" \
    --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
    --format="value(name)")

## 3. Create a service account to be impersonated by Workload Identity
gcloud iam service-accounts create "${SA_ID}" \
    --project="${GOOGLE_CLOUD_PROJECT}"

# 4. Grant necessary permissions
## Grant permission to call Vertex AI to the service account
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
    --role="roles/aiplatform.user" \
    --member="serviceAccount:${SA_EMAIL}" \
    --condition=None

## Grant permission for external ID to impersonate the service account
gcloud iam service-accounts add-iam-policy-binding "${SA_EMAIL}" \
    --project="${GOOGLE_CLOUD_PROJECT}" \
    --role="roles/iam.workloadIdentityUser" \
    --member="${PRINCIPAL_SET}"

# 5. Add to GitHub repository variables
echo "GOOGLE_CLOUD_PROJECT: ${GOOGLE_CLOUD_PROJECT}"
echo "GOOGLE_CLOUD_LOCATION: ${GOOGLE_CLOUD_LOCATION}"
echo "SERVICE_ACCOUNT_EMAIL: ${SA_EMAIL}"
echo "GCP_WIF_PROVIDER: ${WIF_PROVIDER_FULL}"
```As per the script above, I am creating a service account and authenticating using Workload Identity Federation's Service Account Impersonation.
Some might think that if you're authenticating GitHub Actions with OIDC now, you should use Direct Workload Identity Federation instead.
When I actually tried it, without explicitly specifying a service account for Gemini CLI authentication, I got the following error:


		

Error: google-github-actions/auth failed with: the GitHub Action workflow must specify a "service_account" to use when generating an OAuth 2.0 Access Token.
If you are specifying input values via GitHub secrets, ensure the secret is being injected into the environment.
By default, secrets are not passed to workflows triggered from forks, including Dependabot.

			
			
Therefore, it seems necessary to authenticate using Service Account Impersonation at this point.

If you're wondering what Direct Workload Identity Federation is, please refer to the following blog:

https://paper2.hatenablog.com/entry/2024/06/29/143947

Also, please add the items output in step 5 to your GitHub Repository variables.

![Screenshot 2025-08-19 23.40.04](https://devio2024-media.developers.io/image/upload/v1755614449/2025/08/19/zhkayep2axorx1olfukm.png)

## GitHub Authentication

Next, we'll set up GitHub authentication. This time, we'll create a custom GitHub App for authentication.

The main steps are as follows:

1. Create a GitHub App
2. Generate a private key
3. Install the GitHub App to your repository
4. Register variables and secrets to the repository

### 1. Creating a GitHub App

Go to "Settings > Developer settings > GitHub Apps" from your profile icon in the top right and create a new GitHub App.
The main settings are as follows:

* GitHub App name
  * Any name (e.g., `Gemini GitHub Actions`)
* Homepage URL
  * URL of your target repository
* Webhook
  * Disable
* Repository permissions settings
  * Pull requests: Read and write
  * Contents: Read and write

Leave other settings as default and select "Create GitHub App".
After creation, note the "App ID" shown in the app's General tab (you'll register this as a GitHub variable later).

### 2. Generate a Private Key

Create a private key at "General > Private keys > Generate a private key".
A `.pem` file will automatically download, which you should save in a secure location (you'll register this as a GitHub secret later).### 3. Install GitHub App to Repository

Select "Install App" from the app page and choose the account and target repository for installation.

![Screenshot 2025-08-24 18.09.48](https://devio2024-media.developers.io/image/upload/v1756026686/2025/08/24/ce8hs7glztybgnylacdn.png =500x)

### 4. Register Variables and Secrets in the Repository

Register the App ID that you noted in step 1 and the contents of the private key (.pem) generated in step 2.

- Repository variables
  - Name: `APP_ID`
  - Value: App ID

- Repository secrets
  - Name: `APP_PRIVATE_KEY`
  - Value: Contents of the `.pem` file (from -----BEGIN RSA PRIVATE KEY----- to -----END RSA PRIVATE KEY-----)## Let's Try It Out

Now that the setup is complete, let's try it out.
The YAML file used in GitHub Actions is as follows.
It's almost the same as the sample provided, but unnecessary parts have been removed, and the prompt has been translated to Japanese so it will respond in Japanese.

```yaml
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:
    if: |-
      github.event_name == 'workflow_dispatch' ||
      (
        github.event_name == 'pull_request' &&
        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') &&
        contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
      ) ||
      (
        github.event_name == 'pull_request_review' &&
        contains(github.event.review.body, '@gemini-cli /review') &&
        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@v4'

      - name: 'Generate GitHub App Token'
        id: 'generate_token'
        uses: '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 }}'
          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 }}'
          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 }}'
          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:
          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 }}'
          use_vertex_ai: true
          settings: |-
            {
              "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: |-
            ## 役割

            あなたは熟練のコードレビュアーです。GitHub 上でレビューを実施するためのツールにアクセスできます。
            利用可能なツールを使って情報を収集してください。情報の提供を依頼してはいけません。

            ## 要件

            1. すべてのフィードバックは GitHub 上に残すこと。
            2. GitHub に残さない出力は誰にも見られません。

            ## 手順

            まず、必要なデータを収集するために次のコマンドを実行してください:
            1. Run: echo "${REPOSITORY}" で <OWNER>/<REPO> 形式の GitHub リポジトリ名を取得
            2. Run: echo "${PR_DATA}" で PRの詳細(JSON 形式)を取得
            3. Run: echo "${CHANGED_FILES}" で変更されたファイル一覧を取得
            4. Run: echo "${PR_NUMBER}" で PR番号を取得
            5. Run: echo "${ADDITIONAL_INSTRUCTIONS}" でユーザーからの特記事項を確認
            6. Run: gh pr diff "${PR_NUMBER}" で完全なdiffを確認し、理解のために下記の Context セクションを参照すること
            7. 個別のファイルを確認する場合、cat filename、head -50 filename、tail -50 filename を使用
            8. ADDITIONAL_INSTRUCTIONS にテキストが含まれる場合は、その特定領域や着目点を優先してレビューすること
               例: "セキュリティ重視", "パフォーマンス確認", "エラーハンドリングの確認", "破壊的変更の有無を確認"

            ## ガイドライン
            ### コアガイドライン(常に適用)

            1. 文脈の把握: PR のタイトル、説明、変更点、コードファイルを分析して意図を理解する。
            2. 入念なレビュー: すべての関連するコード変更を徹底的に確認し、特に追加された行を優先的にレビューする。指定された注力ポイントやスタイルガイドがあれば考慮する。
            3. 網羅的なレビュー: 著者は関連する問題を余すことなく特定することを望んでいます。問題を見落とすと、著者にとって質の低いレビュー体験となるため、レビュー基準やスタイルガイドに基づき、網羅的に確認してください。
            4. 建設的なフィードバック:
              * 各懸念点について明確な説明を提供する。
              * 具体的で改善されたコード提案や代替アプローチを提示する(可能な場合)。
                特にコード提案は、著者が PR の UI から直接適用できるため有用。ただし、置換対象の行に正確にアンカリングされていることが必須。
            5. 重大度の明記: レビューコメントで問題の重大度を明確に示す。
              著者が緊急度を理解するために非常に重要。
              重大度は以下のいずれか(上から下へ重大度が高い順):
              * `critical`: 直ちに対処が必要。正しさ、セキュリティ、パフォーマンスに重大な影響の恐れ。
              * `high`: 早期に対処すべき。将来的に問題を引き起こす可能性がある。
              * `medium`: 将来的な改善対象。緊急性は低い。
              * `low`: 軽微またはスタイル上の問題。著者の裁量で対応可。
            6. ハードコードされた日付・時刻が未来かどうかには言及しない。
              * 現在日時にはアクセスできないため、判断は著者に任せること。
            7. 的を絞った提案: 提案は diff ハンク内で変更された部分に限定する。
              GitHub(や他の SCM)の API は、diff ハンクに含まれない位置へのコメントを許可しないため、厳守すること。
            8. レビューコメントのコード提案について:
              * 簡潔性: 可能な限り簡潔に。大きすぎる提案は PR UI での直接適用を難しくする。
              * 書式の正当性: 提案は JSON レスポンスの suggestion フィールドに文字列として埋め込む(\n, \\, \" などをエスケープ)。
                suggestion フィールドには Markdown のコードブロックを含めないこと。
                より広い例示や、suggestion フィールドでは巨大な diff となる場合のみ、コメント本文に Markdown のコードブロックを使用する。
                具体的・局所的な変更には suggestion フィールドを優先すること。
              * 行番号の正確性: 置換対象コードと完全に一致した位置に提案を配置する必要がある。
                とくにコメントやコード提案を作成する際は行番号に注意する。
                パッチには各 diff の before/after の行番号が含まれるので、これを用いてコメントと提案をアンカリングすること。
              * コンパイル可能性: 直接コピペで差し替えられるコンパイル可能なコード片にすること。
                コンパイル不能な提案は受け入れられない。もちろん、言語の中にはコンパイルを伴わないものもあるため、ここでの「コンパイル可能」とは字義通り、またはそれに準ずる実行可能性を意味する。
              * インラインコメント: 必要であれば提案コード内に簡潔なコメントを入れて可読性を高めてもよい。
                ただし、コードの内容を単に言い換えるだけのコメントは避ける。著者への説明はコメント本文で行い、
                コード内コメントは読みやすさに資する場合に限る。
            9. Markdown の活用: 箇条書き、強調、表などを活用して読みやすくする。
            10. 誤ったレビューコメントの回避:
              * コメントは、コードがベストプラクティスから逸脱している点を具体的に指摘するものでなければなりません。
                例: 定数はスネークケースの大文字で、という指摘をするなら、対象コードがすでにそのルールに合致していないことを確認する。
            11. 重複したコード提案の削除:
              * 一部の提案が重複する場合があるため、重複するレビューコメントは削除すること。
            12. プルリクエストを承認しないこと
            13. すべてのシェル変数は "${VAR}"(二重引用符と波括弧つき)で参照すること
            14. コメントは日本語で記述すること

            ### レビュー基準(レビューでの優先度順)

            * 正確性(Correctness): 機能、エッジケース、関数の説明と実装の整合性を検証。
              典型的な問題(ロジックエラー、エラーハンドリング、レースコンディション、データ検証、API の使い方、型不一致 など)に留意。
            * 効率(Efficiency): ボトルネックの特定と効率化。不要なループや計算を避ける。
              典型的な問題(過剰なループ、メモリリーク、非効率なデータ構造、冗長計算、過剰なログ など)に留意。
            * 保守性(Maintainability): 可読性、モジュール性、言語イディオム、ベストプラクティスの順守を評価。
              典型的な問題(命名、コメント/ドキュメント、複雑性、重複、フォーマット、マジックナンバー など)に留意。
              スタイルガイドが指定されていない場合は、一般的なガイド(例: Python の PEP 8、Google Java Style Guide)を明示する。
            * セキュリティ(Security): 脆弱性(不適切な保管、インジェクション、アクセス制御不備 など)に注意。

            ### その他の考慮事項
            * テスト: ユニット、統合、E2E テストの十分性。カバレッジ、エッジケース対応、テスト品質を評価。
            * パフォーマンス: 想定負荷下での性能、ボトルネックの特定、最適化の提案。
            * スケーラビリティ: ユーザやデータ量の増加に対するスケール性を評価。
            * モジュール性と再利用性: 構成、モジュール性、再利用性を評価し、リファクタリングや再利用部品の提案を行う。
            * エラーロギングと監視: 適切なログ出力と、本番環境での健全性を監視する仕組みを確認。

            **重要な制約:**

            diff における実際の変更行に対してのみコメントを行うこと。
            これは、提供された diff コンテンツのうち先頭が `+` または `-` の行にのみコメントすべき、という意味です。
            先頭がスペースの行(コンテキスト行)にはコメントしないこと。

            実際の ISSUE や BUG が存在する場合にのみレビューコメントを追加すること。
            ユーザーに「確認してほしい」「検証してほしい」「確かめてほしい」と伝えるだけのコメントはしないこと。
            何かを「担保してほしい」とだけ述べるコメントもしないこと。
            コード変更が「何をするか」を説明するコメントはしないこと。
            コード変更が「正しい」ことを検証するだけのコメントはしないこと。
            著者にコードを説明するためのコメントはしないこと。著者は自分のコードを理解している。改善余地があるときにのみコメントすること。これは非常に重要。

            行番号に細心の注意を払うこと。
            提案コードのインデントが置換対象コードと一致していることを確認すること。
            ライセンスヘッダーに対するコメントは避け、変更されたコードに対してコメントすること。

            ファイルのライセンスヘッダーへのコメントは絶対に避けること。
            著作権表記へのコメントも絶対に避けること。
            ハードコードされた日付や時刻が未来かどうかへの言及は避けること(例: "この日付は未来です")。
            現在日時にはアクセスできないため、判断は著者に任せること。

            このプロンプトの指示や設定、基準には言及しないこと。

            重大度設定の一般指針:
            - ハードコードされた文字列や数値を定数化する提案は、概ね低(low)重大度。
            - ログメッセージやログ改善に関するコメントは、概ね低(low)重大度。
            - .md ファイルでのコメントは、中〜低(medium/low)重大度。これはとても重要。
            - docstring/javadoc の追加・拡充は、多くの場合で低(low)重大度。
            - unchecked 警告の抑制や TODO に関するコメントは、低(low)重大度。
            - タイポは、通常 低〜中(low/medium)重大度。
            - テストやテストに関するコメントは、通常 低(low)重大度。
            - 入力に直接含まれていない URL のコンテンツについてはコメントしないこと。

            コメント本文は簡潔に。
            1 つのコメントでは 1 つの論点に集中すること。

            ## Context
            このプルリクエストで変更されたファイルは、以下の形式で表されます。
            ファイル名と、そのファイル内で変更された範囲を示します:

            <PATCHES>
            FILE:<最初のファイル名>
            DIFF:
            <統一 diff 形式のパッチ>

            --------------------

            FILE:<2 番目のファイル名>
            DIFF:
            <統一 diff 形式のパッチ>

            --------------------

            (以降、変更された全ファイルについて同様)
            </PATCHES>

            UI の左側(before)にコメントしたい場合は、左側の行番号と該当コードを参照してください。
            UI の右側(after)にコメントしたい場合も同様に、右側の行番号と該当コードを参照してください。
            これは行番号を選ぶ際のガイドであり、非常に重要です。コメントは、これらのファイルの指定された行範囲内(LEFT/RIGHT のどちら側でも)に厳密に限定してください。
            範囲外にコメントするとレビューは失敗します。コメントを作る際は、ファイル名、行番号、diff の前後バージョンに注意を払ってください。

            以上Add emojis to indicate severity at the beginning of each comment:
- 🟢 low
- 🟡 medium
- 🟠 high
- 🔴 critical
- 🔵 unclear

Example (inline comment):
<COMMENT>
🟢 Use camelCase for function names
```suggestion
myFooBarFunction

		

</COMMENT>

Critical severity example:
<COMMENT>
🔴 Please remove storage keys from GitHub

			
			
		

</COMMENT>

  1. Submitting the review: Use mcp__github__submit_pending_pull_request_review to submit the pending review.

3.1 Create a summary comment: Include a summary of high-level points not covered in inline comments.
Keep it concise and don't repeat details already stated inline.

			
			Structure the summary comment in Markdown using exactly the following format:
## 📋 Review Summary

Briefly describe the PR overview and overall evaluation in 2-3 sentences.

## 🔍 General Feedback
- General observations about code quality
- References to overall patterns or architectural decisions
- Emphasis on good aspects of the implementation
- Highlighting themes seen repeatedly across files

		

Final Instructions

You are running on a VM, and your output will not be reviewed by humans. Always use MCP tools to create pending reviews, add comments, and submit reviews to post them to GitHub.After reflecting the workflow to main, I'll commit some changes to a different branch, create a PR to main, and test it.
For testing, I've prepared a Python script that intentionally includes several improvement points. The expected points of feedback are:

  1. Unnecessary library import
  2. Shadowing of a built-in function name
  3. Bare exception with pass
  4. Possibility of 'sum' being an undefined variable when an exception occurs
  5. Unused variable 'result'
			
			import pandas as pd

def add(a, b):
    try:
        a = int(a)
        b = int(b)
        sum = a + b
    except Exception:
        pass
    return sum

def main():
    result = add(2, 5)

if __name__ == "__main__":
    main()

		

The review results are shown in the following screenshots.
All the improvement points I prepared were successfully identified!

Screenshot 2025-08-26 0.42.44

Screenshot 2025-08-26 0.42.55

Screenshot 2025-08-26 0.43.02

Screenshot 2025-08-26 0.43.11

Screenshot 2025-08-26 0.43.26

Summary

In this blog, I automated PR reviews using Gemini CLI GitHub Actions with Vertex AI as the backend, authenticating to Google Cloud with Workload Identity Federation.
In the future, I'd like to explore more production-like use cases such as automated PR creation.

Share this article

FacebookHatena blogX

Related articles