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が通ればautomerge | Claudeの出番なし |
| 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のサブスクリプションの利用枠が使われます。ラベルで対象を絞る構成にしたのは、このためでもあります。
手順のまとめ
- Renovateはmajorと0.x系のPRに
needs-claude-reviewを付ける。Dependabotは対象ラベルを付けず、SemVerのmajorラベルをワークフローのifで見る(0.x系はパッケージ名をifに書き、exclude-patternsでグループから外す) - minor・patchは、必須チェックを設定したうえでautomergeに回す
- 対象ラベル(Dependabotはmajorラベルとbotの条件)が付いたPRだけで走るワークフローを作り、
allowed_botsにbotの名前を入れる - 検証手順を
CLAUDE.mdに書き、Claudeには読ませて報告させるだけにする - マージの最終判断は必須チェックと人が持つ