cimg/node のバージョンアップデートを Renovate で管理する
これはなに
CircleCI が提供する Docker イメージ cimg/node のバージョンアップデートを Renovate で適切に管理するための設定手順をまとめたものです。
Renovate による Node.js のアップデート管理
Renovate は以下のファイルに記載されている Node.js のバージョンのうち LTS バージョンのみを自動で検知し、アップデート Pull Request を作成します。
-
package.json中のenginesフィールド -
package.json中のvoltaフィールド .nvmrc.node-version.tool-versions-
.travis.yml中のnode_jsフィールド
cimg/node について
cimg/node は Node.js がインストールされた Docker イメージであり、CircleCI で Node.js を使用する際によく使われています。このイメージのバージョン表記はインストールされている Node.js のバージョンを表しており、 例えばcimg/node:18.13.0 は Node.js のバージョン 18.13.0 がインストールされた Docker イメージです。
問題なのは cimg/node が先述した Node.js の管理対象外であることです。単純な SemVer に準拠したバージョンアップデートなら管理してくれますが、全てのアップデートを検知してしまうため、このままでは LTS 以外の不要な Pull Request も作成されてしまいます。つまり package.json や .nvmrc などに記載されているバージョンと一致しなくなるリスクがあるため、どうにかして cimg/node も LTS バージョンのみを対象とする必要があります。
ゴール
-
cimg/nodeのバージョンアップデートはpackage.jsonや.nvmrcに記載されている Node.js のバージョンと足並みを揃える。 - Node.js のバージョンアップデートは LTS バージョンのみを対象とする。
サンプルプロジェクト
設定手順
1. Renovate の設定ファイルを作成する
リポジトリーのルート直下に renovate.json を作成します。内容は Renovate を有効化した際に自動生成されるものと同じもので大丈夫です。
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"]
}
2. cimg/node のバージョニングルールを Node.js に揃える
matchPackageNames フィールドに cimg/node を追加した Package Rule を作成し、さらに versioning フィールドに node を指定します。
{
"packageRules": [
{
"groupName": "nodeJs",
"matchPackageNames": ["cimg/node"],
"versioning": "node"
}
]
}
versioning は、対象をどのようなバージョニングルールで管理するかを指定するフィールドです(デフォルトは SemVer)。node と指定することで、Node.js の LTS バージョンのみを対象としたルールが適用されます。
ここまでの設定内容
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"timezone": "Asia/Tokyo",
"separateMultipleMajor": true,
"separateMinorPatch": true,
"packageRules": [
{
"groupName": "nodeJs",
"matchPackageNames": ["cimg/node"],
"versioning": "node"
}
//...
]
}
これで cimg/node と package.json + .nvmrc ( + .node-version ) のアップデートにおける足並みが揃うようになりました。
cimg/node |
![]() |
package.json+ .nvmrc + .node-version
|
![]() |
課題: 1つの Pull Request にまとめたい
バージョニングのルールは揃ったものの、Pull Request が別々に作成されてしまうのは問題です。Renovate は様々な設定を公式プリセットとして提供しており、その中に group:nodeJs というものがあります。これを extends フィールドから指定することで利用・拡張することで cimg/node を package.json や .nvmrc と同じ扱いにできないか試みたのですが、残念ながらうまくいきませんでした。
{
"packageRules": [
{
"groupName": "nodeJs",
+ "extends": ["group:nodeJs"],
"matchPackageNames": ["cimg/node"],
"versioning": "node"
}
]
}
結果は変わらず、cimg/nodeの Pull Request は package.json とは別々に作られてしまいます。公式ドキュメントや Issue にもそれらしい情報は見当たらなかったので現状は諦めていますが、もしどなたか知見をお持ちでしたらご教示いただけると幸いです。
追記: extends せず必要なフィールドのみ指定することで解決
group:nodeJs を extend するのではなく、その中から必要なフィールドを抜き出して指定することで期待通りの挙動となります[1]。以下は group:nodeJs のソースコードです。
上記のうち matchDepNames, matchPackagePatterns を流用します。
{
"packageRules": [
{
"groupName": "nodeJs",
- "extends": ["group:nodeJs"],
- "matchPackageNames": ["cimg/node"],
+ "matchDepNames": ["node"],
+ "matchPackagePatterns": ["/node$"],
"versioning": "node"
}
]
}
"matchPackagePatterns": ['/node$'] は cimg/node にもマッチするため matchPackageNames フィールドは不要となります。
これでようやく期待通りの挙動となりました。Pull Request が 1 つにまとまり、かつ cimg/node のバージョンアップデートは package.json と同じ扱いになっています。

versioning フィールドも問題なく機能しており、LTS バージョンを対象とした Pull Request のみが作成されています。

なぜ group:nodeJs の extend ではうまくいかないのか
公式ドキュメントには記載されていないのですが、そもそも group preset の extend は非推奨とのことです(実行ログに警告が出力される)。
また、詳細は不明ですが matchDatasources: ['docker'] があると期待通りの挙動とならないようです。
それならば group:nodeJs を extend したうえで matchDatasources を上書きすればよいのではと考えたものの、このフィールドは mergeable: true 扱いのため上書きができないようです。
参考文献
-
弊社の有識者よりご指摘いただきました。 ↩︎


Discussion