Dependabot のワイルドカードグループが cooldown を無効化する罠と対策de

Dependabot のワイルドカードグループが cooldown を無効化する罠と対策de

Dependabot のワイルドカードグループ patterns: ["*"] が cooldown をバイパスし、pnpm 11 の minimumReleaseAge エラーを引き起こす罠とその対策を解説します。
2026.07.18

はじめに

CI で突然こんなエラーが出ました。

[ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION] 1 lockfile entries failed verification:
  prettier-plugin-tailwindcss@0.8.1 was published at 2026-07-15T11:40:26.000Z,
  within the minimumReleaseAge cutoff (2026-07-15T01:45:56.100Z)

pnpm 11 のサプライチェーン防御機能 minimumReleaseAge(デフォルト24時間)が、公開されたばかりのパッケージをブロックしています。でも、Dependabot の cooldownsemver-patch-days: 3 を設定しているはず——なぜ3日待たずに PR が作られたのか?

調査してみると、Dependabot のグループ化設定に落とし穴があることがわかりました。

Dependabot cooldown と pnpm minimumReleaseAge の関係

まず、この2つの仕組みの違いを整理します。

レイヤー 仕組み タイミング 目的
Dependabot cooldown PR 作成を遅延 Dependabot が PR を開く前 不安定なリリース直後の更新を避ける
pnpm minimumReleaseAge pnpm install 時にブロック CI/ローカルでのインストール時 サプライチェーン攻撃の防御

両者は独立して動作します。Dependabot が PR を作成しても、pnpm が別途パッケージの公開日をチェックします。理想的には cooldown の日数 >= minimumReleaseAge に揃えることで、Dependabot が PR を作る頃にはパッケージがインストール可能になっています。minimumReleaseAge の詳細や推移的依存での問題については「pnpm v11のminimumReleaseAgeでDependabotのCIが落ちる」を参照してください。

当プロジェクトの設定:

dependabot.yml
cooldown:
  default-days: 7
  semver-major-days: 14
  semver-minor-days: 7
  semver-patch-days: 3

pnpm 11 のデフォルト minimumReleaseAge は 1440 分(24時間)。semver-patch-days: 3 なら余裕で超えるはず。では何が起きたのか?

ワイルドカードグループの罠

問題の dependabot.yml 設定:

dependabot.yml
groups:
  dependencies:
    patterns:
      - "*"

すべての依存関係を1つの PR にまとめる設定です。レビューの手間を減らすために入れがちですが、これが cooldown を無効化していました

原因の特定

Dependabot が作った PR を調べると:

  • PR タイトル: "Bump the dependencies group in /frontend with 2 updates"
  • 含まれるパッケージ:
    • prettier 3.9.4 → 3.9.5(公開日: 7月9日、7日経過)
    • prettier-plugin-tailwindcss 0.8.0 → 0.8.1(公開日: 7月15日、14時間経過)

prettier@3.9.5 は7日前に公開されており、semver-patch-days: 3 のクールダウンを通過します。グループ更新はこの「資格のある」パッケージによってトリガーされ、まだクールダウン期間内の prettier-plugin-tailwindcss@0.8.1 も一緒に掃き込まれたのです。

検証

# prettier 3.9.5 の公開日を確認
curl -s "https://registry.npmjs.org/prettier" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); print(d['time']['3.9.5'])"
# 2026-07-09T16:17:00.997Z  ← 7日前、cooldown 通過

つまり、グループ内のパッケージ単位でのクールダウン評価は行われない。1つでも資格を満たすパッケージがあれば、グループ全体がトリガーされます。

dependabot-wildcard-group-cooldown-trap-flow

対策: ワイルドカードグループの削除

修正は単純です。groups セクションを削除します。

dependabot.yml
updates:
 - package-ecosystem: "npm"
   directory: "/frontend"
   schedule:
     interval: "weekly"
   cooldown:
     default-days: 7
     semver-major-days: 14
     semver-minor-days: 7
     semver-patch-days: 3
-  groups:
-    dependencies:
-      patterns:
-        - "*"

グループを削除すると各パッケージが個別の PR になりますが、cooldown が PR 作成を遅延するため、実際にはそれほど PR が増えません。

transitive dep を Dependabot で管理する

caniuse-lite のような頻繁に更新される transitive dep も同様の問題を起こします。以前は pnpm の minimumReleaseAgeExclude で除外していましたが、パッケージ年齢チェックの除外はサプライチェーン防御を弱めます。

より良いアプローチ:

  1. package.json に明示的に追加して Dependabot の管理対象にする
  2. cooldown が適用されるため、公開直後の更新は自動的に遅延される
  3. minimumReleaseAgeExclude は不要になる
frontend/package.json
{
  "devDependencies": {
    "caniuse-lite": "^1.0.30001803"
  }
}

knip(unused dependency checker)が「使われていない依存関係」と報告する場合は、ignoreDependencies に追加します:

knip.json
{
  "ignoreDependencies": ["caniuse-lite"]
}

Dependabot のカバレッジ漏れ

調査中にもう1つ問題を発見しました。knip が v5.88.1 のまま、v6(2026年3月リリース)に更新されていませんでした。

原因: knip はルートの package.json にあり、Dependabot は /frontend ディレクトリしか監視していなかったのです。

dependabot.yml
# /frontend のみ対象 — ルートは対象外だった
- package-ecosystem: "npm"
  directory: "/frontend"

修正: ルートディレクトリ用のエントリを追加。

dependabot.yml
# Root npm dependency updates
- package-ecosystem: "npm"
  directory: "/"
  schedule:
    interval: "weekly"
  cooldown:
    default-days: 7
    semver-major-days: 14
    semver-minor-days: 7
    semver-patch-days: 3

pnpm workspace を使っている場合、ルートの package.json にある devDeps(リンター、フォーマッター等)は見落としがちです。

knip v5 → v6 の変更点

ついでに knip を v6 にアップグレードしました。主な変更点:

項目 v5 v6
パーサー TypeScript oxc-parser + oxc-resolver
速度 - 大幅に高速化
Node.js 要件 v18+ v20.19.0+
プラグイン検出 - PostCSS 等の検出が改善

v6 では PostCSS プラグインの検出が改善され、ignoreDependencies から postcss を削除できるようになりました。一方で、スクリプト内のシステムバイナリ(ssh-keygen, lsof 等)の検出も改善されたため、ignoreBinaries への追加が必要でした。

まとめ

問題 根本原因 対策
minimumReleaseAge violation グループが cooldown をバイパス ワイルドカードグループを削除
minimumReleaseAgeExclude の乱用 transitive dep を Dependabot で管理していない 明示的な devDep に昇格
knip が4ヶ月更新されていない ルート package.json が Dependabot 対象外 directory: "/" を追加

Dependabot でグループ化する場合の注意点:

  • ワイルドカード * グループは cooldown の意味を失わせる
  • グループを使うなら、意味のある単位(react関連、testing関連など)で分ける
  • または、グループを使わず cooldown に PR 頻度の制御を任せる

Dependabot cooldown と pnpm minimumReleaseAge を正しく連携させるには、両方のレイヤーを理解した上で、グループ化がそれを壊さないか確認することが重要です。

この記事をシェアする

関連記事