🤖

Dependabot / Renovate PR のレビューを Claude Code Action に任せたら快適になった

に公開

はじめに

こんにちは、READYFOR のテックリード兼フロントエンドエンジニアの菅原(@kotarella1110)です!

皆さん Dependabot や Renovate を活用して日々ライブラリのアップデートを行なっていますか?

READYFOR では年々リポジトリの数が増えており、Dependabot / Renovate を導入しているリポジトリは21件に上ります。これらのリポジトリに作成されるライブラリアップデート PR を10名程度のメンバーで日々メイン業務と並行して対応しています。
リポジトリが増えるにつれて PR が溜まっていく状況が続き、「ライブラリアップデートをもっと楽にしたい!」という声が社内で高まっていました。

本記事では、そんな中で導入した Claude Code Action を活用した Dependabot / Renovate PR の自動レビュー運用について紹介します。

これまでのライブラリアップデートを楽にする取り組み

依存関係更新の PR 対応を楽にするために、これまでも色々と工夫してきました。

  • devDependencies 且つマイナー以下のアップデートは自動マージ
  • アップデート前後のビルド結果の差分を自動出力
  • 関連ライブラリのグルーピング
  • インテグレーションテストの拡充や VRT の導入
  • マルチリポジトリのモノレポ化

しかし、半数以上の PR は手動での対応が必要であり、その度にライブラリの更新内容をチェンジログやリリースノートで確認、既存コードへの影響範囲を調査、修正といった作業が発生します。
特に複数のバージョンを跨ぐ更新の場合、各バージョンの変更を追うだけでも結構な時間がかかってしまいます。
そんな中で、社内メンバーの mo. さんが Claude Code を活用してライブラリアップデートの手動での対応を楽にして、個人の対応数を大幅に増やすことに成功した事例を紹介してくれました。

https://zenn.dev/readyfor_blog/articles/4dcb1ff5604f83

各々のメンバーが個別にカスタムスラッシュコマンドで Claude に依頼するスタイルも良いのですが、PR が作成されたタイミングで自動的にレビューコメントを投稿してくれたらもっと楽なのになーと思い、Claude Code Action を使って Dependabot / Renovate PR を自動レビューさせる運用を今月(2025年12月)から始めてみました。

Dependencies PR Auto Review with Claude

設定例

実際に現在運用している Claude Code Action による自動レビュー workflow です。
READYFOR の技術スタックは主に Rails と React なので、gem と npm にある程度寄った内容になっていますが、他の言語・パッケージマネージャーでも応用できると思います。

dependabot-claude-pr-auto-review.yml
dependabot-claude-pr-auto-review.yml
name: Dependencies PR Auto Review with Claude

on:
  pull_request:
    types: [opened, reopened]

permissions:
  contents: read
  pull-requests: write
  id-token: write

jobs:
  dependencies-review:
    if: |
      github.actor == 'dependabot[bot]' ||
      github.actor == 'renovate[bot]'
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
        with:
          fetch-depth: 1

      - name: Review dependencies with Claude
        uses: anthropics/claude-code-action@6337623ebba10cf8c8214b507993f8062fd4ccfb # v1.0.22
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            # 依存関係更新の自動レビュー

            **PR**: https://github.com/${{ github.repository }}/pull/${{ github.event.number }}

            この PR で行われる依存関係の更新について、以下の手順で調査・分析を行い、レビューコメントを投稿してください。

            ## 調査手順

            ### 1. PR 情報の取得と差分の確認

            まず、以下のコマンドで PR の基本情報と変更内容を取得してください:

            ```bash
            gh pr view ${{ github.event.number }} --json title,body,files
            gh pr diff ${{ github.event.number }}
            ```

            ### 2. 更新対象のライブラリ特定

            package.json、Gemfile などの差分から、以下を特定してください:
            - 更新されるライブラリ名
            - 更新前のバージョン
            - 更新後のバージョン
            - セマンティックバージョニングの種類(major/minor/patch)

            ### 3. リリースノート・チェンジログの調査

            WebFetch または WebSearch ツールを使って、以下の情報源からリリースノートを探してください:

            - GitHub リポジトリの Releases ページ(例:`https://github.com/{org}/{repo}/releases`)
            - CHANGELOG.md や HISTORY.md
            - 公式ドキュメントのリリースノートセクション
            - npm の Changes タブ(npm パッケージの場合)

            **重要**:複数のバージョンをまたぐ更新の場合は、各バージョンの変更内容を確認してください。

            ### 4. ライセンス情報の確認

            更新前後のライセンスを確認し、変更があった場合は報告してください。

            #### 4.1 ライセンス情報の取得方法

            **Ruby gem の場合**:
            ```bash
            # 現在のバージョン(更新前)のライセンス
            gem spec <gem-name> -r -v <old-version> licenses

            # 新しいバージョン(更新後)のライセンス
            gem spec <gem-name> -r -v <new-version> licenses
            ```

            **npm パッケージの場合**:
            ```bash
            # 現在のバージョン(更新前)のライセンス
            npm view <package-name>@<old-version> license

            # 新しいバージョン(更新後)のライセンス
            npm view <package-name>@<new-version> license
            ```

            #### 4.2 ライセンス変更の検出

            - 更新前後でライセンスが変わっている場合は、その旨を明記
            - ライセンスが見つからない場合や確認できない場合は、その旨を記載
            - 複数ライセンス(デュアルライセンスなど)の場合は、全て記載

            #### 4.3 ライセンス変更時の影響と対応

            ライセンスが変更された場合、以下の点を調査して記載してください:

            **プロダクト側で必要な対応**:
            - **ライセンス通知の更新**: プロダクトのライセンス表示や NOTICE ファイルの更新が必要
            - **利用規約の確認**: 新しいライセンスが既存の利用規約と互換性があるか確認
            - **コピーレフト条項**: GPL などのコピーレフト型ライセンスへの変更の場合、プロダクトのソースコード公開義務が発生する可能性
            - **商用利用の制限**: 商用利用に制限がないか確認
            - **帰属表示**: ライセンスによっては特定の帰属表示が必要

            **具体的な確認事項**:
            1. 新しいライセンスの種類(MIT、Apache、GPL など)
            2. 以前のライセンスとの主な違い
            3. プロダクトへの影響(特に商用利用やソースコード公開義務)
            4. 必要なアクション(ライセンス表示の更新、法務部門への確認など)

            ### 5. 変更内容の要約と分類

            リリースノートから以下を抽出・整理してください:

            #### 🚨 Breaking Changes(破壊的変更)
            - API の変更、削除
            - 動作の変更
            - 最低要件の変更(Node.js バージョン、依存関係など)

            #### ✨ 新機能
            - 追加された機能
            - パフォーマンス改善

            #### 🐛 バグ修正
            - 修正されたバグ
            - セキュリティ修正

            #### 📦 依存関係の変更
            - 追加・更新・削除された依存関係

            **説明のポイント**:
            - 専門用語は極力使わず、使う場合は簡単な補足を入れる
            - ライブラリをほとんど知らないエンジニアでも理解できるように平易な言葉で説明

            ### 6. 既存コードの影響範囲分析

            **重要**: この手順は漏れがないよう、必ず**すべてのステップを順番に実行**してください。

            #### 6.1 ライブラリの機能把握
            - 更新対象のライブラリが提供している主要な機能・API を理解してください
            - 公式ドキュメントやリポジトリの README を参照し、主要なエクスポート、コンポーネント、関数をリストアップ

            #### 6.2 段階的な検索の実施

            以下の検索を**順番にすべて**実行してください。`{library-name}` を実際のライブラリ/gem 名に置き換えてください。

            **Phase 1: ライブラリ名での包括的検索**

            Grep ツールを使って、更新対象のライブラリの使用箇所を**漏れなく**検索してください。

            **JavaScript/TypeScript/Node.js パッケージの場合:**
            - ES Module import (`import ... from 'library-name'`)
            - CommonJS require (`require('library-name')`)
            - Dynamic import (`import('library-name')`)
            - Re-export (`export ... from 'library-name'`)
            - TypeScript type import (`import type ... from 'library-name'`)
            - サブパスインポート (`library-name/...`)

            **Ruby gem の場合:**
            - require 文 (`require 'library-name'`)
            - require_relative 文
            - Gemfile 内の gem 宣言 (`gem 'library-name'`)
            - autoload 文
            - gem が提供する主要なクラス/モジュール名(リリースノートや README から特定)

            **その他の言語:**
            - Python: `import library-name`, `from library-name import`
            - Go: `import "library-name"`
            - その他の言語も同様に、その言語の import/require 構文で検索

            **Phase 2: ライブラリ固有の使用パターン検索**

            ライブラリの種類に応じて、以下の追加検索を実行してください:

            - **React/Vue コンポーネントライブラリの場合**:
              - 主要コンポーネント名を JSX/テンプレート内で検索
              - 例:`pattern: <ComponentName`(開始タグ)

            - **Rails gem の場合**:
              - 設定ファイル(`config/initializers/`, `config/application.rb`)を検索
              - マイグレーションファイルでの使用を確認

            - **CLI ツールの場合**:
              - package.json の scripts セクションを Read ツールで確認(Node.js)
              - Rakefile でのタスク定義を確認(Ruby)
              - ライブラリのコマンド名を検索

            - **設定ファイル用ライブラリの場合**:
              - 設定ファイル(`.config.js`, `.rc`, `package.json`, `.rubocop.yml` など)を検索
              - 例:`eslint`, `prettier`, `webpack`, `rubocop` など

            - **ビルドプロセスで使用されるライブラリの場合**:
              - Dockerfile での使用を検索(特に `.docker/` ディレクトリ)
              - docker-compose.yml での使用を確認
              - アセットビルドやコンパイルステップでの使用
              - CI/CD 設定ファイル(`.github/workflows/` など)での使用

            - **型定義ライブラリの場合**(`@types/*`):
              - 対応する実体ライブラリの使用箇所を検索

            **Phase 3: 主要 API の検索**

            リリースノートで変更があった主要な API や関数がある場合:
            - それらの名前でコードベース全体を検索
            - 誤検出を避けるため、見つかったファイルを Read ツールで確認

            #### 6.3 検索結果の検証

            **検索結果が見つかった場合**:
            1. **重要**: 見つかった**全てのファイル**を Read ツールで開いて、実際の使用状況を確認してください
            2. 見つかった**全てのファイル**について、以下を記録:
               - ファイルパスと行番号(markdown リンク形式:`[ファイル名](パス#L行番号)`)
               - 該当するコードスニペット(前後数行含む)
               - どの API/機能を使用しているか
               - 想定される影響(破壊的変更がある場合)
            3. **省略厳禁**:...など」「その他」などで省略せず、検索で見つかった全ての使用箇所を必ず報告してください

            **検索結果が 0 件の場合**:
            1. package.json/Gemfile を Read ツールで確認し、dependencies/devDependencies に本当に含まれているか確認
            2. 含まれている場合:
               - 異なる検索パターンを試す(大文字小文字、エイリアス、グローバル変数など)
               - 間接的な依存の可能性を調査(他のライブラリが内部で使用)
            3. 含まれていない場合:
               - 依存関係の依存(transitive dependency)である可能性を明記

            #### 6.4 影響範囲の判定基準

            -**影響範囲に含めるべき**:
              - ライブラリの API を直接呼び出している箇所
              - ライブラリのコンポーネントを使用している箇所
              - ライブラリの型定義を使用している箇所
              - 設定ファイルでライブラリを参照している箇所
              - Dockerfile やビルドプロセスでライブラリを使用している箇所
              - アセットのコンパイルやプリコンパイルでライブラリを使用している箇所
              - CI/CD パイプラインでライブラリを使用している箇所

            -**影響範囲に含めない**:
              - 実際には使用されていない import 文のみ(Dead code)
              - コメント内での言及のみ
              - 間接的な依存で、直接のコード変更が不要な場合

            #### 6.5 報告形式

            **使用箇所が見つかった場合**:

            **重要**: 検索で見つかった**全てのファイル**を番号付きリストで記載してください。省略は絶対に禁止です。

            ```markdown
            #### 📁 使用箇所
            以下の **N**のファイルで `{library-name}` が使用されています:

            1. [ファイル名](相対パス#L行番号)
               ```言語
               コードスニペット
               ```
               - **使用している機能**: 機能名や API 名
               - **影響**: 破壊的変更がある場合の影響を記載

            2. [ファイル名](相対パス#L行番号)
               ```言語
               コードスニペット
               ```
               - **使用している機能**: 機能名や API 名
               - **影響**: 破壊的変更がある場合の影響を記載

            ... (以下、見つかった全てのファイルを同様の形式で記載)

            N. [ファイル名](相対パス#L行番号)
               ```言語
               コードスニペット
               ```
               - **使用している機能**: 機能名や API 名
               - **影響**: 破壊的変更がある場合の影響を記載
            ```

            **注意**:
            - 必ず「N 件」の部分に実際の件数を記載してください
            -...」や「その他」などで省略せず、全ての使用箇所を記載してください
            - ファイル数が多い場合(10 件以上)でも、全て列挙してください

            **使用箇所が見つからなかった場合**:
            ```markdown
            #### 📁 使用箇所
            直接の使用箇所は見つかりませんでした。

            - `{library-name}` は package.json/Gemfile の dependencies に含まれていますが、
              コードベース内で直接インポート・使用している箇所は検出されませんでした。
            - 間接的な依存関係(他のライブラリが内部で使用)の可能性があります。
            ```

            **検証の完了確認**:
            - [ ] Phase 1 のすべての検索パターンを実行した
            - [ ] Phase 2 のライブラリ固有パターンを確認した
            - [ ] Phase 3 の主要 API を検索した(該当する場合)
            - [ ] 見つかった**全てのファイル**を Read で確認した
            - [ ] **全ての使用箇所**を報告に記載した(省略なし)
            - [ ] package.json/Gemfile で依存関係を確認した

            ## レビューコメントの投稿

            調査結果を以下の形式でまとめ、`gh pr comment` コマンドで投稿してください:

            ```markdown
            ## 🤖 Claude による依存関係レビュー

            ### 📦 更新内容
            - **ライブラリ**: {ライブラリ名}
            - **バージョン**: {旧バージョン}{新バージョン}
            - **変更種別**: {Major/Minor/Patch}

            ### 📝 リリースノート
            {リリースノートの URL}

            ### 📄 ライセンス情報
            {ライセンスが変更された場合のみ記載}
            - **更新前**: {旧ライセンス}
            - **更新後**: {新ライセンス}

            #### ⚠️ ライセンス変更の影響
            {ライセンスが変更された場合、プロダクト側で必要な対応を記載:
            - ライセンス通知の更新が必要か
            - 利用規約との互換性確認が必要か
            - コピーレフト条項による影響はあるか
            - 商用利用に制限はないか
            - 帰属表示の変更が必要か}

            ### 🚨 Breaking Changes
            {破壊的変更がある場合のみ記載}

            ### ✨ 主な変更内容
            {変更内容の要約}

            ### 🔍 影響範囲分析
            {使用箇所の分析結果}

            ### ✅ 推奨アクション
            {必要な対応があれば記載、なければ「特になし」}

            ---
            <!-- dependencies-claude-review -->
            ```

            **コメント投稿時の注意**:
            既存のコメントがある場合は上書き、ない場合は新規作成してください。以下の手順で実行してください:

            1. **既存のコメント ID を検索**:
               ```bash
               COMMENT_ID=$(gh api repos/${{ github.repository }}/issues/${{ github.event.number }}/comments \
                 --jq '.[] | select(.body | contains("<!-- dependencies-claude-review -->")) | .id' | head -n 1)
               ```

            2. **コメントの投稿または更新**:
               ```bash
               COMMENT_BODY="...コメント内容..."

               if [ -n "$COMMENT_ID" ]; then
                 # 既存コメントを更新
                 gh api --method PATCH "repos/${{ github.repository }}/issues/comments/$COMMENT_ID" \
                   -f body="$COMMENT_BODY"
               else
                 # 新規コメントを作成
                 gh pr comment ${{ github.event.number }} --body "$COMMENT_BODY"
               fi
               ```

            3. コメントには必ず識別子 `<!-- dependencies-claude-review -->` を含めてください

            ## 注意事項
            - PR ブランチは既にチェックアウト済みです
            - Claude の対話応答として表示せず、必ず `gh pr comment` コマンドで PR にコメントを投稿してください
            - 不明な点や確信が持てない場合は、その旨を正直に記載してください
            - 複数のライブラリが更新される場合は、それぞれについて調査してください

          claude_args: |
            --allowedTools "Bash(gh pr:*),Bash(gh api:*),Bash(gem spec:*),Bash(npm view:*),WebSearch,WebFetch,Read,Glob,Grep"

プロンプトの工夫ポイント

実際に運用してみて、精度を上げるために工夫したポイントを紹介します。

分かりやすい変更の要約

リリースノートには専門用語が多く含まれていることが多いため、できるだけ平易な言葉で要約するように指示しています。

影響範囲分析の徹底

導入当初は影響範囲の分析が甘く、Dockerfile や GitHub Actions で使用されているのに見落とされてしまうレビューコメントが確認されました。プロンプトで IMPORTANT だと強調し、段階的な検索手順を明確にすることで、見落としは今の所確認されていません。

ライセンス変更の自動検出

ライセンス変更はライブラリのアップデートで見落とされがちな項目です。
そのため、ライセンス変更を検出する専用 workflow を作る予定だったんですが、Claude にやらせてしまった方が楽だったので、ライセンス情報の確認と変更検出もプロンプトに組み込みました。
まあ、実際のところライセンス変更はそんなに頻繁に起こるわけじゃないので、今のところ恩恵を感じたことはないんですが・・・

Claude Code Action のレビューコメント

以下は @swc/core のアップデート PR に対して Claude Code Action が実際に投稿したレビューコメントです。

Claude Code Action のレビューコメント

レビューコメント全体

🤖 Claude による依存関係レビュー

📦 更新内容

  • ライブラリ: @swc/core
  • バージョン: 1.15.1 → 1.15.3
  • 変更種別: Patch

📝 リリースノート

📄 ライセンス情報

ライセンスの変更はありません(Apache-2.0)。

✨ 主な変更内容

🐛 バグ修正(v1.15.3)

  • コメントの出力: トップレベルのコメントが欠落していた問題を修正し、全てのノードでコメントが適切に出力されるようになりました
  • 最適化の改善: 副作用を持つ式(side effects)が誤って変換されないように、圧縮処理(compress.comparisons)が修正されました
  • デッドコード除去: 使用されていないアロー関数が適切に削除されるようになりました
  • パーサー修正: プログラムの範囲(span)が入力の開始位置から正しく始まるようになりました
  • プラグイン対応: コンパイルエラーを防ぐために条件付きコンパイル(cfg属性)が適用されました
  • 内部モジュール: swc_atoms から swc_core::atoms への移行が完了しました

⚡ パフォーマンス改善(v1.15.3)

  • 正規表現処理(regexp pass)と名前空間エクスポート(export_namespace_from)が Transformer に統合され、処理が高速化されました

🐛 バグ修正(v1.15.2)

  • ファイル名オプション: print() 関数の filename オプションが正しく尊重されるようになりました

✨ 新機能(v1.15.2)

  • 空のコンストラクタ削除: 最小化(minification)時に空のコンストラクタが自動的に削除されるようになりました
  • 訪問フック拡張: VisitMutHook トレイトにコンテキストパラメータが追加され、より柔軟な変換が可能になりました

⚡ パフォーマンス改善(v1.15.2)

  • パーサーの skip_space 関数がインライン化され、skip_block_comment の外側ループが削除されました
  • プラグインで共有 tokio ランタイムを使用することで、ランタイム作成のオーバーヘッドが削減されました

🔍 影響範囲分析

📁 使用箇所

以下の 2 件のファイルで @swc/core が間接的に使用されています:

  1. jest.config.js
    (社内コードのため省略)

  2. webpack.config.js
    (社内コードのため省略)

📚 その他の参照箇所

  • README.md: ドキュメントに SWC の使用が記載されています(直接の影響なし)
  • CLAUDE.md: ドキュメントに SWC の使用が記載されています(直接の影響なし)

✅ 推奨アクション

特に対応は不要です。 今回の更新は以下の理由から安全です:

  1. パッチアップデート: マイナーバージョンの範囲内でのバグ修正とパフォーマンス改善のみです
  2. 破壊的変更なし: API の変更や動作の変更はありません
  3. 品質向上: コメントの出力、最適化の精度、デッドコード除去が改善されます
  4. パフォーマンス向上: トランスパイルとビルドの処理速度が改善されます

推奨される確認事項

  • CI/CD パイプラインでのテストとビルドが成功することを確認してください
  • 特に npm testnpm run build の実行が正常に完了するか確認してください

導入効果

導入してまだ半月程度のため正確な効果を断言できませんが、12月12日時点(10営業日)での推移を見てみます。

月別の合計マージ数(自動マージを除く):

月別の合計マージ数の推移を示す棒グラフ。8月は438件、9月は536件、10月は573件、11月は532件、12月予想は634件と過去最高を記録している。

1営業日あたりの平均マージ数(自動マージを除く):

1営業日あたりの平均マージ数の推移を示す棒グラフ。8月は21件、9月は28.2件、10月は26件、11月は29.6件、12月は31.7件と過去最高を記録している。

10月が月別の合計マージ数の過去最高、11月が1営業日あたりの平均マージ数の過去最高だったんですが、運用開始から半月程度の12月は、それらをさらに上回るペースです。
とはいえ、この変動は誤差の範囲な気もするため、今後数ヶ月先まで継続的に観測していく予定です。

運用してみて感じたメリット・デメリット

実際に半月ほど運用してみて感じたことをまとめます。

メリット

  • ライブラリアップデート PR を開くとすでに変更内容や影響範囲がコメントされているので、「ちょっと見てみるか」という気持ちになりやすい(心理的なハードルが下がった)。
  • リリースノートを読んで、影響範囲を調べて...という作業が自動化されたので、作業コストが大幅に削減されました。モノによりますが、1件あたり10〜20分くらいは削減できている感覚です。
  • 経験が浅いメンバーでもレビューコメントを読めばある程度判断できるようになりました。
  • PR 上にレビューコメントが残るので、過去のアップデート内容を振り返りやすい。

デメリット

  • Anthropic API のコストがそれなりにかかります。READYFOR では Claude Code Action 1回の実行で約0.52ドル(50回実行での平均値)のコストがかかっていました。ただ、人件費と天秤にかけると十分ペイすると考えています。[1]
  • 当たり前ですが、Claude の出力が常に正確とは限らないため、特に影響範囲が広いアップデートは人間が最終的にレビュー・判断する必要があります。

おわりに

Claude Code Action による Dependabot / Renovate PR の自動レビューは想像以上に快適で、ライブラリアップデートに対する心理的なハードルやストレスが大幅に軽減されました。
とはいえ、まだ運用を始めたばかりのため今後もプロンプトの改善や運用ルールの見直しを継続していく予定です。特にコスト面についてはラベルやアサインが付与された PR のみに自動レビューを限定するなど、最適化の余地があると考えています。

導入効果についても現時点では十分なデータが揃っていないため、数ヶ月運用した上で改めて計測し長期的にどの程度効果が持続するのかを評価していきたいと思います。

同じような課題を抱えている方はぜひお試しください!


明日の READYFOR Advent Calendar 2025 の 17日目は @hxdegawa さんによる記事です。お楽しみに!

脚注
  1. READYFOR では過去4ヶ月で月平均約877件のライブラリアップデート PR がオープン(8月748件、9月1,153件、10月922件、11月683件)、約520件がマージ(8月438件、9月536件、10月573件、11月532件)されています。Claude Code Actionは PR のオープン時に実行されるため、月間の API 実行回数はオープン数とほぼ同じです。月877件として計算すると、API コストは約68,000円/月(877回 × 0.52ドル × 150円/ドル)。一方、人件費削減の効果はマージされた PR に対してのみ発生するため、1件あたり10分の作業時間削減として、月間約87時間(520件 × 10分 / 60)の削減。エンジニアの時給を5000円で計算すると約43.3万円/月の人件費削減になります。差し引き約36.5万円/月の純利益、ROI は約537%となり十分にコスパが良いです。 ↩︎

GitHubで編集を提案
READYFORテックブログ

Discussion