はじめに
前回の記事では、Copilot SDK を使って GitLab のマージリクエスト(MR)を自動レビューするツールを紹介しました。 前回は Docker やローカル環境から手動で実行する方法でしたが、実際の開発フローでは MR が作成されるたびに自動でレビューが走ってほしいところです。
今回はこのレビューツールを GitLab CI/CD パイプラインに組み込み、MR 作成時に自動でコードレビューを実行する方法を紹介します。
使用するリポジトリ
前回と同じく以下のリポジトリを使用します。
CI の前準備:GitLab Runner の設定
GitLab CI を実行するには、GitLab Runner が必要です。 Runner がまだ登録されていない場合は、以下の手順で Docker ベースの Runner を追加してください。 すでに Runner が設定済みの場合はこのセクションをスキップして構いません。
Runner コンテナを追加する
docker-compose.yml に gitlab-runner サービスを追加します。
services:
gitlab:
# (既存の gitlab サービス設定)
gitlab-runner:
image: gitlab/gitlab-runner:ubuntu-v18.8.0
container_name: gitlab-runner
restart: always
depends_on:
- gitlab
volumes:
- ./gitlab-runner/config:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock/var/run/docker.sock をマウントすることで、Runner がホストの Docker デーモンを使用して CI ジョブ用のコンテナを起動できるようになります。
注意:
gitlab-runnerのバージョンは GitLab CE のバージョンに合わせて選択してください。
コンテナを起動します。
docker compose up -dRunner を GitLab に登録する
起動した gitlab-runner コンテナ内で登録を行います。
docker exec -it gitlab-runner bash
gitlab-runner register対話形式で以下の情報を入力します。
| 項目 | 入力値 |
|---|---|
| GitLab instance URL | GitLab の URL(例: http://gitlab) |
| Registration token | GitLab 管理画面から取得したトークン |
| Runner name | 任意(例: shared-runner) |
| Executor | docker |
| Default Docker image | alpine:latest |
登録トークンは、GitLab の Admin Area > Runners > Create Instance Runner から確認できます。
登録が完了すると Runner registered successfully. と表示されます。
動作確認として、適当なプロジェクトに簡単な .gitlab-ci.yml を置いてパイプラインが実行できることを確認しておきましょう。
runner-check:
stage: test
tags:
- docker
script:
- echo "Runner is working!"全体の流れ
GitLab CI 上での動作は以下のようになります。
- 開発者が MR を作成(または更新)する
- GitLab CI がマージリクエストパイプラインをトリガーする
- CI ジョブがレビューツールのリポジトリをクローンし、ビルド・実行する
- Copilot SDK が MR の差分を解析し、懸念点をインラインコメントとして MR に投稿する
CI 上で実行する場合、CI_PROJECT_ID や CI_MERGE_REQUEST_IID といった GitLab の定義済み変数が利用できるため、手動で指定する項目が減ります。また、CI/CD 設定でシークレット変数を管理できるため、トークンの取り扱いも整理しやすくなります。
.gitlab-ci.yml の設定
レビューしたいリポジトリに以下の CI 設定ファイルを追加します。
stages:
- review
copilot-review:
stage: review
tags:
- docker
image: node:22-slim
before_script:
- apt-get update && apt-get install -y git
variables:
GITLAB_PROJECT_ID: $CI_PROJECT_ID # プロジェクト ID を自動取得
GITLAB_MR_IID: $CI_MERGE_REQUEST_IID # マージリクエスト IID を自動取得
PROJECT_DIR: $CI_PROJECT_DIR # CI がチェックアウトしたディレクトリを使用
script:
- git clone --depth 1 https://github.com/shutils/gitlab-ci-review.git # 適宜バージョン固定することも検討
- cd gitlab-ci-review
- npm ci
- npm run build
- node dist/index.js
rules:
- if: >-
$CI_PIPELINE_SOURCE == "merge_request_event" &&
$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" &&
$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature\//ポイント
image: node:22-slimを使用しているため、before_scriptでgitをインストールしています。Node.js が含まれるイメージであれば他のイメージでも構いませんPROJECT_DIRに$CI_PROJECT_DIRを指定することで、CI が自動チェックアウトしたリポジトリをそのまま使い、レビュー対象リポジトリの再クローンを省略できますrulesセクションでmerge_request_eventを条件にしているため、MR パイプラインでのみ実行されます。条件はプロジェクトの運用に合わせて適宜変更してください
rules のカスタマイズ例
上記の例では develop ブランチへの feature/* ブランチからの MR のみを対象にしていますが、プロジェクトに応じて条件を変更できます。
# すべての MR で実行する場合
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# main ブランチへの MR のみ
rules:
- if: >-
$CI_PIPELINE_SOURCE == "merge_request_event" &&
$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"CI/CD 変数の設定
GitLab の Settings > CI/CD > Variables から以下の変数を登録します。
| 変数名 | 必須 | 説明 | 設定例 |
|---|---|---|---|
GITLAB_TOKEN | ✅ | GitLab のアクセストークン。MR の差分取得やコメント投稿に使用 | glpat-xxxxxxxxxxxx |
GITHUB_TOKEN | ✅ | GitHub のパーソナルアクセストークン。Copilot SDK の認証に使用 | github_pat_xxxxxxxxxxxx |
GITLAB_URL | GitLab インスタンスの URL。GitLab.com を使う場合は省略可 | https://gitlab.example.com | |
REVIEW_MODEL | 使用する Copilot モデル名。省略時は gpt-5-mini | gpt-5-mini | |
REVIEW_LANG | レビューコメントの言語。省略時は英語 | Japanese |
トークンに必要な権限
GitLab Access Token (GITLAB_TOKEN)
MR の差分取得とコメント投稿のため、以下のスコープが必要です。
api:MR の差分取得・ディスカッション作成に使用
Personal Access Token のほか、プロジェクト単位で発行できる Project Access Token も利用可能です。 Project Access Token を使えば権限のスコープをプロジェクトに限定できるため、セキュリティの観点ではこちらが推奨されます。
GitHub Personal Access Token (GITHUB_TOKEN)
Copilot SDK の認証に使用します。Copilot サブスクリプション(Business または Enterprise)に加入しているアカウントで発行する必要があります。
変数の保護設定
変数を登録する際は、以下の設定を確認してください。
- Mask variable:有効にすると、CI ジョブのログにトークンの値が表示されなくなります。必ず有効にしてください
- Protect variable:有効にすると、保護ブランチ・保護タグのパイプラインでのみ変数が利用可能になります。レビュー対象のブランチが保護ブランチでない場合は無効にしてください
- Expand variable reference:変数の値に
$が含まれない限り、デフォルトのままで問題ありません
セキュリティ上の注意
外部リポジトリのクローンに関するリスク
上記の .gitlab-ci.yml では git clone で外部リポジトリ(gitlab-ci-review)をクローンしています。 この方法はシンプルですが、クローン先のリポジトリの内容が改ざんされた場合、CI 環境内のシークレット(GITLAB_TOKEN や GITHUB_TOKEN)が漏洩するリスクがあります。
たとえば、クローンしたリポジトリの package.json の postinstall スクリプトや、ソースコード自体にトークンを外部に送信するコードが仕込まれていた場合、npm ci や node dist/index.js の実行時にトークンが詐取される可能性があります。
このリスクを軽減するために、以下の対策を検討してください。
1. 特定のコミットハッシュやタグを指定してクローンする
script:
- git clone --depth 1 --branch v1.0.0 https://github.com/shutils/gitlab-ci-review.gitブランチ名(main など)ではなく、タグやコミットハッシュを指定することで、意図しない変更が紛れ込むリスクを減らせます。
2. フォークして自組織のリポジトリで管理する
外部リポジトリをフォークし、コードレビューを経てから自組織のリポジトリにマージすることで、実行するコードの内容を管理下に置けます。
script:
- git clone --depth 1 https://gitlab.example.com/internal/gitlab-ci-review.git3. Docker イメージとしてビルド済みのものを使う
レビューツールをあらかじめ Docker イメージとしてビルドし、プライベートレジストリに格納しておく方法もあります。
copilot-review:
stage: review
image: registry.example.com/internal/gitlab-ci-review:v1.0.0
variables:
GITLAB_PROJECT_ID: $CI_PROJECT_ID
GITLAB_MR_IID: $CI_MERGE_REQUEST_IID
PROJECT_DIR: $CI_PROJECT_DIR
script:
- node dist/index.jsこの方法であれば、CI ジョブ内で外部リポジトリのクローンやビルドが不要になり、サプライチェーン攻撃のリスクを大幅に軽減できます。
トークンの最小権限の原則
CI で使用するトークンは必要最小限の権限に留めることが重要です。
GITLAB_TOKENは Project Access Token を使い、対象プロジェクトのみにスコープを限定するGITHUB_TOKENは Copilot の利用に必要なスコープのみを付与する- 定期的にトークンをローテーション(再発行)する運用を組み込むと安全性が向上します
トラブルシューティング
パイプラインが実行されない
rulesの条件を確認してください。merge_request_eventをソースとするパイプラインは、MR が作成または更新されたときにのみトリガーされます.gitlab-ci.ymlが MR のソースブランチに含まれていることを確認してください
レビューコメントが投稿されない
GITLAB_TOKENにapiスコープがあるか確認してくださいGITHUB_TOKENが Copilot サブスクリプションに紐づいたアカウントのものか確認してください- CI ジョブのログで Copilot SDK の認証エラーが出ていないかを確認してください
まとめ
Copilot SDK を使った MR レビューツールを GitLab CI に組み込むことで、MR 作成時に自動でコードレビューを実行できるようになります。 CI/CD 変数でトークンを管理し、rules でパイプラインの実行条件を制御することで、実際の開発フローに自然に組み込めます。 外部リポジトリをクローンして実行する構成では、サプライチェーン攻撃のリスクがあるため、タグ固定やフォーク管理、Docker イメージ化といった対策を組み合わせることも検討してみてください。


コメント