GitHub

[GitHub] Dependabot入門:依存パッケージの更新をPull Requestで安全に管理する

Webアプリケーションでは、フレームワーク、UIライブラリ、テストツールなど、多くの外部パッケージを利用します。
これらのパッケージには、新機能だけでなく、不具合修正やセキュリティ修正も継続的に提供されます。

しかし、すべての更新を人が定期的に調べ、変更ファイルを作り、Pull Requestを準備するのは大きな負担です。
この作業を支援するGitHubの機能が Dependabot です。

本記事では、Dependabotが何を自動化し、何を人が判断すべきなのかを、npmプロジェクトの設定例とともに解説します。

Dependabotとは

Dependabotは、リポジトリで利用している依存パッケージをGitHubが監視し、更新が必要な場合にPull Requestを作成する機能です。

例えば、プロジェクトが次のパッケージを利用しているとします。

{
  "dependencies": {
    "astro": "7.1.6",
    "react": "19.2.8",
    "zod": "4.4.3"
  }
}

新しいバージョンが公開されると、Dependabotは設定に従って更新を確認します。
更新対象が見つかれば、おおむね次の処理を行います。

  1. 更新用のブランチを作成する
  2. package.jsonpackage-lock.jsonを更新する
  3. 変更内容を記載したPull Requestを作成する
  4. 設定されていればラベルや担当者を付ける

Dependabotは、通常の開発者と同じように「変更をPull Requestとして提案」します。
設定ファイルを置いただけで、本番環境へ勝手に反映されるわけではありません。

2種類の更新

Dependabotの更新は、主に次の2種類に分かれます。

Version updates

新しいバージョンが公開されているかを定期的に確認し、更新用Pull Requestを作ります。

セキュリティ上の問題がなくても、次のような目的で更新が提案されます。

  • 不具合修正を取り込む
  • 新機能を利用する
  • 古いバージョンの利用を避ける
  • 将来の大規模アップデートを小さくする

Version updatesは、.github/dependabot.ymlをリポジトリに追加することで有効化できます。

Security updates

既知の脆弱性が検出されたとき、修正版へ更新するPull Requestを作ります。
利用には、リポジトリのDependency graph、Dependabot alerts、Dependabot security updatesなど、GitHub側のセキュリティ設定も関係します。
Version updatesが「定期的な保守」であるのに対し、Security updatesは「既知の脆弱性への対応」と考えると分かりやすいでしょう。

最小構成のdependabot.yml

Dependabotの設定ファイルは、リポジトリの次の場所に置きます。

version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly

各項目の意味は次のとおりです。

設定意味
version: 2Dependabot設定ファイルの形式
package-ecosystem: npmnpmの依存パッケージを監視する
directory: /package.jsonなどがリポジトリ直下にある
interval: weekly毎週更新を確認する

アプリケーションがサブディレクトリにある場合は、directoryを変更します。

directory: /frontend

実用的な設定例

次は、更新タイミング、対象ブランチ、PR数、ラベルを設定した例です。

version: 2
updates:
  - package-ecosystem: npm
    directory: /frontend
    schedule:
      interval: weekly
      day: monday
      time: "09:00"
      timezone: Asia/Tokyo
    target-branch: develop
    open-pull-requests-limit: 5
    labels:
      - dependencies
      - maintenance

この設定では、Dependabotは次のように動きます。

  • /frontendのnpmパッケージを監視する
  • 毎週月曜日の午前9時ごろに確認する
  • develop向けにPull Requestを作成する
  • 同時に開くversion updateのPull Requestを最大5件にする
  • 指定したラベルを付ける

target-branchを省略した場合は、通常はリポジトリのデフォルトブランチが更新先になります。ブランチ運用を採用している場合は、更新PRをどこへ作るか明示した方が安全です。

更新をグループ化する

パッケージ数が多いプロジェクトでは、1パッケージにつき1件のPull Requestが作られると、確認作業が増えすぎることがあります。

groupsを使うと、複数の更新を1件のPull Requestへまとめられます。

groups:
  production-dependencies:
    dependency-type: production
  development-dependencies:
    dependency-type: development

この例では、アプリケーション本体で利用する依存と、テストや開発で利用する依存を分けてグループ化します。

この例では、アプリケーション本体で利用する依存と、テストや開発で利用する依存を分けてグループ化します。

ただし、すべての依存をまとめると、問題が発生したときに原因を特定しにくくなります。影響が大きいパッケージは個別のPull Requestにする方が安全です。

重要パッケージを個別PRにする

フレームワーク、UIランタイム、スキーマ検証、ビルド・デプロイ基盤などは、更新の影響範囲が大きくなりがちです。

exclude-patternsを使うと、指定したパッケージをグループから除外できます。

groups:
  production-dependencies:
    dependency-type: production
    exclude-patterns:
      - astro
      - "@astrojs/react"
      - react
      - react-dom
      - zod

  development-dependencies:
    dependency-type: development
    exclude-patterns:
      - typescript
      - wrangler

除外されたパッケージの更新は無視されるのではありません。
グループに含めず、個別のPull Requestとして提案されます。

この構成には次の利点があります。

  • 更新による影響をパッケージごとに確認できる
  • 不具合が起きたときに原因を特定しやすい
  • リリースノートや破壊的変更を個別に評価できる
  • 必要なテスト内容をパッケージごとに変えられる

完全固定とlockfile

Dependabotを導入する場合でも、インストールの再現性は別途考える必要があります。

package.jsonには、次のような指定方法があります。

{
  "dependencies": {
    "example-a": "1.2.3",
    "example-b": "^1.2.3",
    "example-c": "~1.2.3"
  }
}
指定一般的な意味
1.2.31.2.3へ固定
^1.2.3同じmajorバージョン内の更新を許可
~1.2.3同じminorバージョン内のpatch更新を許可

どの方式が正しいかは、プロジェクトの方針によります。
ただし、CIや本番ビルドを再現可能にするため、package-lock.jsonなどのlockfileはコミットすることが重要です。

npmでは、CIやクリーン環境で次を使うと、lockfileに基づいて依存関係を復元できます。

npm ci

更新をDependabotのPull Requestに集約したい場合は、直接依存を完全固定し、新規追加時にも完全固定する方法があります。

# .npmrc
save-exact=true

この方法では、依存バージョンの変更がPull Requestの差分として明確になります。

GitHub Actionsと組み合わせる

DependabotがPull Requestを作成しても、更新後のアプリケーションが正常に動くとは限りません。
そこで重要になるのがCIです。

JavaScript/TypeScriptプロジェクトでは、少なくとも次の検証が考えられます。

npm ci
npm run check
npm test
npm run build
npm audit --audit-level=high

ブラウザ上の動作へ影響する更新では、E2Eテストも実行します。

npm run test:e2e

推奨する流れは次のとおりです。

Dependabotが更新を検出
  ↓
更新用Pull Requestを作成
  ↓
GitHub Actionsが型チェック・テスト・ビルドを実行
  ↓
開発者がリリースノートと差分を確認
  ↓
ステージング環境で必要な確認を行う
  ↓
問題がなければ人がマージ

自動マージは慎重に

DependabotのPull Requestを自動マージする仕組みも構築できますが、最初からすべての更新を自動化する必要はありません。

特に次の更新は、人による確認を推奨します。

  • major/minorバージョンの更新
  • フレームワークやUIランタイム
  • データ検証ライブラリ
  • 認証・決済・フォーム関連
  • ビルド・デプロイツール
  • lockfileに大きな変更がある更新

patch更新でも、実装との相性によって不具合が生じることがあります。
まずは「PR作成まで自動化し、マージは人が判断する」運用から始めるのが安全です。

導入後に確認する場所

Dependabotの監視対象や実行状況は、GitHubの次の画面から確認できます。

Repository
→ Insights
→ Dependency graph
→ Dependabot

セキュリティ関連の機能は、リポジトリ設定から確認します。

Repository
→ Settings
→ Security
→ Advanced Security
→ Dependabot

画面名や利用できる機能は、リポジトリ種別、プラン、組織ポリシーによって異なる場合があります。

よくある注意点

directoryが間違っている

package.jsonがサブディレクトリにあるのにdirectory: /としていると、目的の依存関係を監視できません。

ラベルが存在しない

設定したラベルがリポジトリに存在するか確認します。
チーム独自のラベルを使う場合は、先に作成しておくと分かりやすくなります。

更新PRを放置し続ける

DependabotのPull Requestに長期間対応しない状態が続くと、version updatesが一時停止される場合があります。不要なPRは理由を確認して閉じるか、更新方針を調整しましょう。

グループを大きくしすぎる

多くのパッケージを1件にまとめるとレビューは減りますが、テスト失敗時の切り分けが難しくなります。
通常の小規模更新はまとめ、重要な基盤パッケージは個別にする方法が現実的です。

Security updatesとVersion updatesを混同する

定期チェックの設定を追加しただけで、すべてのセキュリティ機能が有効になったとは限りません。
Dependency graph、Dependabot alerts、Dependabot security updatesの状態も確認します。

まとめ

Dependabotは、依存パッケージの更新判断をすべて自動化する機能ではありません。
更新候補の発見とPull Request作成を自動化し、人がレビューしやすい状態に整える機能です。

安全に導入するための要点は次のとおりです。

  • .github/dependabot.ymlで対象、頻度、更新先を明示する
  • lockfileをコミットし、CIではnpm ciを使う
  • 小さな更新は適切にグループ化する
  • 重要なパッケージは個別PRにする
  • GitHub Actionsで型チェック、テスト、ビルドを行う
  • 自動マージは急がず、最終判断を人が行う

Dependabotを「自動アップデート機能」ではなく、「継続的な依存保守のためのPull Request作成担当」と捉えると、導入後の役割分担が明確になります。

参考資料