📆

Renovateでnpmを週単位で管理する設定例

6 min read

概要

Renovate で、npm packeage の更新をある程度まとめて週単位で行うための設定例の解説です。

ある程度まとめたい理由は、リリース作業自体に伴って発生する作業コストを抑えたいためです。自動テストなどの機械的な検証が弱い環境では、この点は重要になると思います。
一方で、リリースを細かく行っても手間が掛からない状況においては、あまり有用な設定ではないかもしれません。

以下、まず設定例を記載して、その後に解説を行う形式で説明します。

設定例

renovate.json
{
  "extends": [
    "config:base"
  ],
  "timezone": "Asia/Tokyo",
  "enabledManagers": [
    "npm"
  ],
  "ignoreDeps": [
    "@types/node",
    "npm"
  ],
  "separateMultipleMajor": true,
  "packageRules": [
    {
      "matchDepTypes": [
        "dependencies"
      ],
      "groupName": "dependencies"
    },
    {
      "matchDepTypes": [
        "devDependencies"
      ],
      "groupName": "devDependencies"
    }
  ]
}
package.json 無関係なフィールドは削除しています。
{
  "dependencies": {
    "foo": "1.2.3"
  },
  "devDependencies": {
    "bar": "1.2.3"
  },
  "engines": {
    "npm": "7.20.3"
  }
}
.npmrc
save-exact=true

解説

バージョン指定は "x.x.x" の完全一致で行う

例えば、バージョン "1.2.3" のパッケージがあったとしたら、下記のような範囲の指定を行わないということです。

  • "^1.2.3"
  • "~1.2.3"
  • "1"

なぜならば、その範囲内の更新を Renovate が無視してしまうためです。
例えば、通常 npm install でインストールした時に登録される "^" の指定があると、major バージョン以外の更新を無視します。

その点、rangeStrategy の設定を "bump" にすると挙動が変わり(現在は "replace")、指定範囲内でも無視しないようになりますが、それならセマンティック・バージョニングの解釈と一致するようにパッケージ側のバージョンを厳密な値へ変更した方が良さそうなので、そちらを選択しました。
npm outdated の出力が Renovate の解釈と似るため、手元で状況を確認したいときに便利という点もあります。

加えて、完全一致へバージョンの表記を統一するのに従い、npm install 時に "^" を除去するために .npmrcsave-exact=true を設定します。

minor 以下の更新は dependenciesdevDependencies の単位でまとめる

minor と patch バージョンの更新は、dependenciesdevDependencies の単位で集約した結果をそれぞれ PR へまとめて提出させます。

例えば、以下のような PR が提出されます。

このようにまとめているのは、minor 以下の更新は基本的には影響が少ないことから、まとめて処理した方が効率的だと判断したためです。
また、「最大 20 PR」「最大 2 PR 提出/時間」のような処理量の制約があり、多くの PR が存在すると不便になるためです。この点は課金で解決できるかもしれませんが、未調査です。

この集約を設定しているのは、主に packageRules に含まれる設定です。
なお、packageRules は、個別のパッケージに対して条件をつけれたり、独自のグルーピングを作って管理したりなどより複雑な設定を行うことができます。

また、major と minor 以下で処理を分ける設定をしているのは、separateMajorMinor です。これは初期値から変更していません。

major の更新はパッケージごとの PR にする

一方で、major バージョンの更新は、パッケージそして 1 バージョンごとにひとつの PR を提出させます。
これは minor 以下とは真逆の理由で、影響の大きいものが多いためです。

そこで、初期設定は major 同士で集約する設定になっていますが、separateMultipleMajor を変更しています。

major と minor 以下の更新が同時に発生したときは、両方の PR へ記載されます。

脆弱性起因のパッケージ更新

vulnerabilityAlerts によると、初期設定で Security Fix は個別に送信されてくるそうです。

engines.npm が Renovate Bot が使う npm バージョンになる

Configuring which version of npm Renovate uses に書いてありました。
設定例のバージョンは仮置きのものなので、お手元のプロジェクトの npm のバージョンに合わせて設定してください。

ただ、ここに記載すると、dependencies へ登録したかのように更新対象へ含まれてしまったので、ignoreDeps で除外しています。

平日は PR を提出しない

schedule"every weekend" を指定して、平日に PR が提出されないようにしています。
npm package の更新作業中に、意図せずに PR の内容が変わらないようにするためです。
every weekend に仕事をされている方は強く生きてください。

また、"every weekend" の具体的な更新時刻はわかりませんでした。土曜なのか日曜なのか土日両方なのか時間はいつなのか、など。

Node.js へ同期する必要があるものは更新対象外

"@types/node"ignoreDeps へ登録している点です。

このような配慮をしている中で、Node.js バージョンの更新がすぐできる可能性は低いためです。

補足

Renovate を GitHub App 経由で導入する手順

調べれば一瞬でわかりそうな話ですが、一応自分のやったことを書いておきます。

  • GitHub App として、Renovate をインストールする。
  • そうすると、新規リポジトリ作成時に Renovate を使うかが選択肢に現れる。
    • リポジトリに対して Renovate の GitHub App を有効にすると、Configure Renovate という PR が自動で送信される。
  • 後は道なりで設定できると思います。
    • なお、最初に拒否したときは、おそらくは Renovate 側の管理サイトである Renovate Dashboard から有効にできるのだと思いますが、まだ試していません。

GitHub App へインストール時に "all repos" を選択した時

導入時のどこかで、"all repos" または "select repos" という感じの選択をどちらかを選ぶところがあるのですが、そこで "all repo" を選ぶと自分の全ての repo へ Configure Revonate の PR が生成されてしまいました。失敗しました。

料金はいくらですか?

少なくとも、GitHub の Public Repository に対して GitHub App で導入した経路だと無料でした。
先ほど書いたように、「最大 20 PR」「最大 2 PR 提出/時間」などの処理量の制約がありますが、それが課金で解決できるのかは不明です。

Dependency Dashboard

Dependency Dashboard という Issue もそのうち自動投稿されます。
ここで概要を確認したり、特定の操作を行うことができます。結構便利でした。

パッケージを更新対象外にする複数の方法

ドキュメント内では、個別のパッケージを更新対象外にすることを "ignore" と表現していますが、この状態にするにはいくつかの手段があります。

ignore した package の Security Fix は提出される?

ドキュメントからはわかりませんでした。

PR と Job を一致する手段がなさそう?

Renovate Dashboard で導入した GitHub リポジトリのプロジェクトをみると、以下のように Job なるビルド結果ログっぽいものが Job ID 付きで保存されていますが、これと PR を一致する手段がわかりませんでした。

Discussion

ログインするとコメントできます