Claude Media
Claude CodeでRenovateとDependabotのPRを検証する運用

Claude CodeでRenovateとDependabotのPRを検証する運用

RenovateとDependabotが立てる更新PRのうち、破壊的変更の疑いがあるものだけをClaude Code Actionに検証させる構成を、両ツールの設定キーとワークフロー例でまとめます。

RenovateとDependabotは更新PRを作るところまでを自動化しますが、そのPRを安全に取り込めるかは人が判断しています。この判断のうち「changelogを読み、型エラーとテストの結果と照らして、影響がありそうか調べる」部分をClaude CodeのGitHub Actionに任せる、というのがこの記事の構成です。全PRに走らせると費用も通知も膨らむので、破壊的変更の疑いがあるPRだけに絞ります。

先に結論を書くと、Claudeを走らせる対象はmajor更新と0.x系の更新に限り、minorとpatchは従来どおりCIの結果とautomergeで流します。

更新PRを3つに振り分ける

Claudeに見せる前に、更新PRを性質で分けておきます。分け方は両ツールの設定で決まるので、Claude側のプロンプトを工夫する前にここを固めるのが先です。

更新の種類扱いClaudeの出番
patch / minor(1.x以降)扱いCIが通ればautomergeClaudeの出番なし
major扱いラベルを付けて人が見るClaudeの出番changelogと影響箇所の調査
0.x系のminor / patch扱いmajorと同じ扱いにするClaudeの出番changelogと影響箇所の調査

0.x系を別に数える理由は、両ツールのドキュメントに書かれた注意にあります。SemVerに従うパッケージでも、0.xではminorやpatchで破壊的変更が入ることがあります(Renovate)。Dependabotはx.y.z形式のバージョンを常にmajor.minor.patchとして扱います。つまり0.x系の更新はminorとして分類され、そのままではmajor向けの絞り込みをすり抜けます。

Renovateで対象PRにラベルを付ける

RenovateはpackageRulesのmatchUpdateTypesで更新の種類を判定できます。majorにラベルを付ける設定と、それ以外をautomergeする設定を並べ、最後に0.x系を例外にするルールを置きます。

{
  "extends": ["config:recommended"],
  "packageRules": [
    {
      "matchUpdateTypes": ["major"],
      "labels": ["needs-claude-review"]
    },
    {
      "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
      "automerge": true
    },
    {
      "matchCurrentVersion": "/^0\\./",
      "automerge": false,
      "labels": ["needs-claude-review"]
    }
  ]
}

3つ目のルールが0.x対策です。matchCurrentVersionは正規表現(/で囲みます)を受け付けるので、現在のバージョンが0.で始まるパッケージだけを拾います。packageRulesは後に書いたルールが先のルールを上書きするため、2つ目で付いたautomergeが0.xでは外れ、ラベルだけが付きます。

ここで気にしたい点が2つあります。

  • matchUpdateTypesの制約: 同じルールの中でallowedVersionsとは併用できません
  • automergeと必須チェック: GitHubのブランチ保護で「Require status checks to pass before merging」に1つもチェックを選んでいないと、プラットフォームのautomergeがテスト失敗のPRを通す可能性があります

changelogの取得はfetchChangeLogsが制御し、既定値はprです。PRの作成・更新時にchangelogやリリースノートを取得してPR本文に載せる設定なので、Claudeに読ませる材料はPRの本文にすでに入っています。branchにすると動作が遅くなるとも書かれているので、変えなくて構いません。

更新PRが一度に増えすぎる場合は、prConcurrentLimit(既定は10、0で無制限)と、更新の一覧を1つのissueに集めるdependencyDashboardが使えます。後者はconfig:recommendedに含まれています。関連パッケージをまとめたいときはgroupNameを使います。

Dependabotで対象PRを絞る

Dependabotは.github/dependabot.ymlで設定します。PRを絞る道具はgroups、ignore、open-pull-requests-limitの3つで、ラベルはlabelsです。

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5
    labels:
      - "dependencies"
    groups:
      non-major:
        update-types:
          - "minor"
          - "patch"
        exclude-patterns:
          - "left-pad"

exclude-patternsは、0.x系のパッケージ(left-padは例)をグループから外す指定です。パターンには*のワイルドカードが使え、グループのパターンと除外パターンの両方に当たる依存関係は除外されます。外したパッケージは個別のPRになり、タイトルにパッケージ名が出ます。後述の0.x対策は、このタイトルを条件に使います。

groupsを使うと、条件に合う依存関係の更新が1本のPRにまとまります。グループに当てはまらない更新は、これまでどおり1依存関係につき1本のPRです。上の例ではminorとpatchが1本にまとまり、majorは個別のPRとして残ります。

labelsはパッケージマネージャー単位の設定で、更新の種類による出し分けはできません。そこで上の例では、needs-claude-reviewのような対象ラベルをlabelsに入れていません。全PRに付いてしまい、まとめたminor / patchのPRまでClaudeが検証することになるからです。SemVerのラベル(major / minor / patch)がリポジトリにあれば、Dependabotがそれも自動で付けます。ワークフロー側でこのSemVerラベルを見て、majorのPRだけを対象にします。

そのほかの既定値も、この運用には効いてきます。

  • open-pull-requests-limitの既定は5で、開いているPRがその数に達すると、マージまたはクローズされるまで新しいバージョン更新のPRは作られません。セキュリティ更新のPRはこの上限の対象外です
  • cooldownを設定しなくても、バージョン更新には既定で3日のクールダウンがかかります。リリース直後の版は3日待ってから対象になり、この既定はセキュリティ更新には適用されません
  • 特定の依存関係やバージョンを外したいときはignoreを使います。allowとignoreの両方に当たる依存関係は無視されます

更新PRでClaude Code Actionを走らせる

ここからがClaude側の設定です。anthropics/claude-code-action@v1は、ワークフローにpromptがあると自動化モードで動き、@claudeのメンションを待たずに走ります。次のワークフローは、対象は2通りです。Renovateが付けたneeds-claude-reviewラベルのPRと、Dependabotが作ってmajorラベルの付いたPRだけを検証します。

name: Dependency PR check
on:
  pull_request:
    types: [opened, synchronize, labeled]
jobs:
  verify:
    if: >-
      contains(github.event.pull_request.labels.*.name, 'needs-claude-review') ||
      (github.actor == 'dependabot[bot]' &&
       contains(github.event.pull_request.labels.*.name, 'major'))
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
      pull-requests: write
      issues: read
      id-token: write
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          allowed_bots: "renovate[bot],dependabot[bot]"
          prompt: |
            PR #${{ github.event.pull_request.number }} は依存関係の更新PRです。
            CLAUDE.md の「依存更新PRの検証手順」に従って調べ、
            結果を PR コメントに投稿してください。
          claude_args: |
            --max-turns 15
            --allowedTools "Bash(gh pr view *),Bash(gh pr diff *),Bash(gh pr comment *),Bash(npm run typecheck),Bash(npm test *),Read,Grep,Glob"

見どころはallowed_botsです。このアクションは、Claudeがループで自分を呼ばないように、botが起こしたイベントを既定で拒否します。RenovateやDependabotが作ったPRで走らせるなら、botの名前をallowed_botsに列挙しなければなりません。上の書き方(renovate[bot]とdependabot[bot])は、GitHub Actions連携の解説にある例と同じです。

promptを渡した自動化モードでは、結果は既定でワークフローのログに出ます。PRにコメントさせたいときは、プロンプトでそう指示したうえで、投稿できるツールを許可します。上の例でgh pr commentを許可し、pull-requests: writeを付けているのはそのためです。プロンプトだけのモードではシェルもGitHub APIも使えない状態から始まるので、--allowedToolsに必要なコマンドを1つずつ書きます。Bash(gh pr view *)のように、*はサブコマンドの後ろに置きます。

費用の上限は--max-turnsとジョブのtimeout-minutesで抑えます。どちらもコスト管理の手段として挙げられているものです。同じPRに対する重複実行が気になるなら、ジョブにconcurrencyを足します。

CLAUDE.mdに検証手順を書いておく

ワークフローのプロンプトを短く保つために、検証の中身はCLAUDE.mdに置きます。Claudeは毎回これを読み、プロジェクトの基準やレビュー基準はCLAUDE.mdに書くのが基本です。検証できる粒度で書くのがコツです。

## 依存更新PRの検証手順
 
1. `gh pr view` でPR本文を読み、changelog の「Breaking」「Removed」
   「Deprecated」に当たる項目を抜き出す
2. `gh pr diff` で lockfile 以外の変更(設定ファイルや型定義)を確認する
3. 抜き出した API 名を Grep し、このリポジトリで使っている箇所を一覧にする
4. `npm run typecheck` と `npm test` を実行し、失敗があれば
   最初のエラーだけを引用する
5. 次の3段階で結論を書く
   - 取り込める: 使用箇所に影響なし、型・テストとも成功
   - 修正が要る: 影響する箇所とファイルを列挙する
   - 判断できない: changelog に該当がなく、根拠が足りない
6. ファイルは編集しない。修正案はコメントに書くだけにする

3段階の結論に「判断できない」を入れておくのが大事です。changelogが薄いパッケージでは、Claudeが根拠なしに「問題なし」と書く余地を残さないほうが、コメントを読む人の手間が減ります。6番でファイルを編集させていないのは、PRのブランチにClaudeが勝手にコミットして、Renovateの更新と競合するのを避けるためです。

型とテストの実行結果を根拠にする点は、ほかの記事の書き方と同じ考え方です。たとえばClaude CodeでTerraformのコードを書く手順では、生成物をplanの差分で確かめています。依存更新でも、Claudeの自己申告ではなく、コマンドの出力を読ませて判断させます。

Claudeの判定を最終ゲートにしない

Claudeのコメントは判断材料であって、マージの承認ではありません。運用では次の線引きを置いておくと崩れにくくなります。

  • Claudeの結論が「取り込める」でも、必須チェック(CIのテスト・ビルド)が通らなければマージしません。Claudeのジョブ自体は必須チェックに入れず、参考情報として扱います
  • majorのPRは、Claudeのコメントの有無にかかわらず人が最後にマージします。Renovate側でmajorにautomergeを設定しません
  • 「判断できない」が続くパッケージは、RenovateならpackageRules、Dependabotならignoreで除外するか、手動更新に切り替えます

権限は必要最小限にして、Claudeの変更はマージ前にレビューするのが基本です。この構成はClaudeにコードを書かせず、読ませて報告させるだけなので、権限はcontents: readで足ります。

つまずきやすい点

Claudeが起動せずにワークフローが失敗する

アクションは実行前に2つの確認をします。1つは、Issueやプルリクエストのイベントでは起こしたユーザーに書き込み権限があること。もう1つは、botでないことです。botが起こした実行はallowed_botsに載せていなければ拒否されます。失敗したジョブのログで、どちらの確認に落ちたかを最初に見ます。

DependabotのPRだけAPIキーが空になる

Dependabotが起こしたpull_requestイベントのワークフローは、フォークから開かれたPRと同じ扱いになります。GITHUB_TOKENは読み取り専用になり、通常のActionsシークレットも渡りません。上のワークフローのままsecrets.ANTHROPIC_API_KEYを参照すると、Dependabot PRでは値が空になり、Claudeは認証できません。

対処は2つです。ANTHROPIC_API_KEYを、Settings > Secrets and variables > Dependabotにも同じ名前で登録します。Dependabotのイベントで使えるのはDependabotシークレットだけで、同名にしておけばワークフローは変更せずに済みます。トークンの権限はpermissionsキーで引き上げます。この記事の例はpull-requests: writeを明示しているので、コメント投稿にはそれで足ります。RenovateのPRにはこの制限はありません。

Claudeが直した内容でCIが走らない

デフォルトのGITHUB_TOKENで作られたコミットでは、GitHubがワークフローを起動しません。github_token: ${{ secrets.GITHUB_TOKEN }}を渡している場合は外して、Claude GitHub Appとして認証させます。この記事の構成ではClaudeにコミットさせませんが、修正まで任せる形に広げたときに当たる点です。

code-reviewプラグインでは代用できない

レビュー用ワークフローは、自動化されたPRや些細なPRをレビュー不要とみなして飛ばします。依存更新のPRはこれに当たる可能性が高いので、上のようにプロンプトを自分で書くほうが確実です。

0.x系がすり抜ける

ラベル付けをmajorだけにすると、0.x系のminor更新にClaudeが走りません。Renovateは上の設定の3つ目のルール(matchCurrentVersion)で拾います。Dependabotは、SemVerラベルだけでは0.xを区別できません。0.x系で使っているパッケージ名を、ワークフローのifに直接書きます。たとえばジョブのifの||の後ろにcontains(github.event.pull_request.title, 'left-pad')(left-padは例)を足すと、タイトルにそのパッケージ名を含むPRが対象に加わります。

ただし、minor / patchをグループにまとめている場合、0.xのパッケージもそのグループPRに入ります。グループPRのタイトルはグループ名が中心で、パッケージ名が出るとは限らないため、この条件をすり抜けます。Dependabotの設定のgroupsにexclude-patternsで同じパッケージ名を書き、個別のPRとして残してください。0.xのパッケージが増えたら、exclude-patternsとifの両方に足します。

PRごとに費用がかかる

各実行は、GitHub Actionsの分数とAPIトークンの両方を消費します。OAuthトークンで認証している場合は、APIの課金ではなくClaudeのサブスクリプションの利用枠が使われます。ラベルで対象を絞る構成にしたのは、このためでもあります。

手順のまとめ

  1. Renovateはmajorと0.x系のPRにneeds-claude-reviewを付ける。Dependabotは対象ラベルを付けず、SemVerのmajorラベルをワークフローのifで見る(0.x系はパッケージ名をifに書き、exclude-patternsでグループから外す)
  2. minor・patchは、必須チェックを設定したうえでautomergeに回す
  3. 対象ラベル(Dependabotはmajorラベルとbotの条件)が付いたPRだけで走るワークフローを作り、allowed_botsにbotの名前を入れる
  4. 検証手順をCLAUDE.mdに書き、Claudeには読ませて報告させるだけにする
  5. マージの最終判断は必須チェックと人が持つ
この記事を共有:XはてブLinkedIn