1.この記事を書こうと思った背景
今更感満載だけれど、パッケージの依存関係の更新ツールである Renovate について理解が浅いと感じることがあった。とりわけ、Presets
や Config
の書き方については見様見真似でやってしまっている感が否めなかった。
そこで、表題のとおり、Renovate を個人リポジトリで小さく始めながら 、Renovate を触っていく上で押さえておきたい点について、この記事に書き留めていきたい。
2.前提と環境情報
Renovate の platform
は https://github.com とし、GitHub App
で運用する。Renovate の導入手順は Installing & Onboarding - Renovate Docs を参考にした。
また、Renovate で指定する更新方法のことを Config
と書いておく。というのも 設定
と日本語で書いてしまうと一般的な「設定」と、Config
のうち、どちらを指して書いているのか、区別することが難しいためである。
3.スタート地点としての [“config:base”]
Renovate の Config
は 設定ファイルに書いていくのだが、公開されている Presets(Config Presets)
を使うこともできる。
たとえば、Shareable Config Presets - Renovate Docs | Renovate Docs で紹介されている、extends: [“config:base”] を指定するだけでも Renovate を使うことができる。
$ cat renovate.json5
{
extends: ["config:base"],
timezone: "Asia/Tokyo"
}
※ renovate.json5
はコメントが書ける renovate.json のようなもの。詳細は、5-4.Renovate の設定ファイルにコメントを書きたい を参照。
※ ["config:base"]
で採用されている Config
は以下のとおり。
{
"extends": [
":dependencyDashboard",
":semanticPrefixFixDepsChoreOthers",
":ignoreModulesAndTests",
":autodetectPinVersions",
":prHourlyLimit2",
":prConcurrentLimit10",
"group:monorepos",
"group:recommended",
"workarounds:all"
]
}
出所:config:base | Full Config Presets - Renovate Docs | Renovate Docs
4.Renovate の Config の適用ロジック
ところで Config
は以下の3つの方法で適用されている。
- 自分で Renovate の設定ファイルで指定
Preset
を使ってRenovate の設定ファイルで指定- Renovate の設定ファイルに書かない
- 設定項目のデフォルト値がある Config はデフォルト値を採用することとなる
- Configuration Options - Renovate Docs | Renovate Docs
$ cat renovate.json5
{
//Preset から指定
"extends": ["config:base"],
//自分で指定
"timezone": "Asia/Tokyo",
"dependencyDashboard": false
}
ここで気になるのが、Config
の適用ロジックだ。たとえば、Preset
と Config
が書かれていたら、どちらから適用されるのだろうか? Renovate の設定ファイルに書かれている順に適用されるのだろうか?
Configuration Options - Renovate Docs | Renovate Docs では、Config
の適用ロジックについて次のように述べられている。
Renovate will evaluate all packageRules and not stop once it gets a first match. … later rules can override settings from earlier rules if needed.
Renovate はすべての packageRule を評価し、最初にマッチするものがあれば停止しません。(略)必要であれば、後のルールが前のルールの設定を上書きすることができます。(DeepLより)
注意するべき点は、冒頭の evaluate all packageRules
と override settings from earlier
の2点だろう。つまり、Config
は Renovate の設定ファイルに書かれている順に適用されるといえる。
4-1.後に書いた Config は前に書いたそれを上書きするのか検証してみた
以下のように dependencyDashboard
を2回設定したら、後に設定した "dependencyDashboard": false
が適用され、Dependency Dashboard は表示されなかった。エラーにもならない。
$ cat renovate.json5
{
"timezone": "Asia/Tokyo",
"dependencyDashboard": true,
"dependencyDashboard": false
}
また、次のように後に "dependencyDashboard": true
や "extends": ["config:base"]
を指定すると、Dependency Dashboard は表示された。
$ cat renovate.json5
{
"timezone": "Asia/Tokyo",
"dependencyDashboard": false,
"dependencyDashboard": true,
}
$ cat renovate.json5
{
"timezone": "Asia/Tokyo",
"dependencyDashboard": false,
"extends": ["config:base"]
}
※ ["config:base"]
は ":dependencyDashboard"
という Preset
を含む点に注意!
Starting from version v26.0.0
the "Dependency Dashboard" is enabled by default as part of the commonly-used config:base preset.
To disable the Dependency Dashboard,
add the preset :disableDependencyDashboard or set dependencyDashboard to false.
出所: dependencyDashboard | Configuration Options - Renovate Docs
このようにルールを複数書いたとしてもエラー扱いとはならないが、読みにくい。ルールをダブらせて指定することはできるだけ避けたほうがよいのではないか?と思う。
4-2.Preset と個別に指定したい Config どちらを先に書くか
最初に Preset
を書いていき、続いて個別に指定したい Config
を都度書いていくべきだろう。
先に個別に指定したい Config
を書いてしまうと、個別に指定したい Config
は、Preset
でセットされている Config
に上書きされてしまう。
$ cat renovate.json5
{
"timezone": "Asia/Tokyo",
"dependencyDashboard": false,
"extends": ["config:base"]
}
5.逆引き
5-1.ドキュメントに沿って設定をしたけどPRがこない
"rangeStrategy"
とバージョンの指定方法を確認する。とくに、"rangeStrategy": "replace"
となっており、かつ、バージョンの指定方法として キャレット(^)
を使っていた場合、更新対象とはならないという。"rangeStrategy": "bump"
を使うようにとのこと。
For example, if your package.json specifies a value for left-pad of ^1.0.0 and the latest version on npmjs is 1.2.0, then Renovate won’t change anything because 1.2.0 satisfies the range. If instead you’d prefer to be updated to ^1.2.0 in cases like this, then configure rangeStrategy to bump in your Renovate config.
出所:rangeStrategy | Configuration Options - Renovate Docs | Renovate Docs
5-2.Schedule の書き方を知りたい
schedule | Configuration Options - Renovate Docs | Renovate Docs で紹介されている。
詳細はドキュメントを参照してほしいが、要点は以下2点。
- Cron 表記で指定するには、cheap-glitch/mi-cron を使う必要があり、また、時間ピッタリでの指定はできない 。
- Schedule Presets を使うとカンタンに Schedule の設定ができるというが、以下のようにそのまま書いてしまってもいいと思う。
{
"schedule": ["after 10pm and before 5am every weekday", "every weekend"]
}
5-3.ローカルで実行したい
npm でインストールするか、コンテナイメージを使うことで、ローカルでも実行できる。以下はコンテナイメージを使った様子。
$ docker run --rm \
> -e RENOVATE_TOKEN=<ghp_personal_acecess_token> \
> -e LOG_LEVEL=debug \
> renovate/renovate:32.72.0 \
> --platform github \
> --dry-run=true \
> gkzz/echo-server-typescript
WARN: cli config dryRun property has been changed to full
INFO: Repository started (repository=gkzz/echo-server-typescript)
"renovateVersion": "32.72.0"
INFO: Dependency extraction complete (repository=gkzz/echo-server-typescript)
"baseBranch": "main",
"stats": {
"managers": {
"dockerfile": {"fileCount": 1, "depCount": 2},
"npm": {"fileCount": 1, "depCount": 11}
},
"total": {"fileCount": 2, "depCount": 13}
}
略
認証トークンを RENOVATE_TOKEN
という環境変数に渡す必要がある。--platform github
の場合、認証トークンは Personal Access Token(PAT)
。
参考:
- Usage | Self-Hosting Examples - Renovate Docs | Renovate Docs
- https://github.com/renovatebot/config-help/issues/570#issuecomment-608469236
5-4.Renovate の設定ファイルにコメントを書きたい
Renovate の設定ファイルは renovate.json
以外にもいくつかの名前やフォーマットに対応している。
- renovate.json
- renovate.json5
- .github/renovate.json
- .github/renovate.json5
- .gitlab/renovate.json
- .gitlab/renovate.json5
- .renovaterc
- .renovaterc.json
- package.json (within a “renovate” section)
出所:Configuration Options - Renovate Docs | Renovate Docs
そのなかで renovate.json5
は renovate.json
と違い、コメントが書ける !
さて、コメントが書けるというのはどういうことか? JSON5 | JSON for Humans によると、JSON5 は ECMAScript 5.1からのいくつかの Production を含むように構文を拡張 したものとあり、そういった構文のひとつが、コメントを許容するという記法だという。
The JSON5 Data Interchange Format (JSON5) is a superset of JSON that aims to alleviate some of the limitations of JSON by expanding its syntax to include some productions from ECMAScript 5.1. …
Single and multi-line comments are allowed.
5-5.Dockerfile で使っているコンテナイメージのバージョンを Renovate で管理したい
docker:enableMajor | Docker Presets - Renovate Docs | Renovate Docs を使うとカンタンにできる。また、multi-stage builds でも問題なくできた。
{
"extends": [
"config:base",
// https://docs.renovatebot.com/presets-docker/
"docker:enableMajor"
]
//略
}
一例として、以下のような Dockerfile で使っている node:16.15.0-slim
のバージョンを管理したいとする。
FROM node:16.15.0-slim AS base
#略
FROM node:16.15.0-slim AS dev
#略
無事、更新できている。
以下は --dry-run=true
でドライランをしたときに表示されたログの抜粋である。
"config": {
"dockerfile": [
{
"packageFile": "Dockerfile",
"deps": [
{
"depName": "node",
"currentValue": "16.15.0-slim",
"currentDigest": "sha256:df27e7dd385d35b7cc48d77d37bfd2e784bb4e2bc56da8ee8818a2a862d555ec",
"replaceString": "node:16.15.0-slim@sha256:df27e7dd385d35b7cc48d77d37bfd2e784bb4e2bc56da8ee8818a2a862d555ec",
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
"datasource": "docker",
"depType": "stage",
"depIndex": 0,
"updates": [
{
"bucket": "non-major",
"newVersion": "16.15.1",
"newValue": "16.15.1-slim",
"newMajor": 16,
"newMinor": 15,
"updateType": "patch",
"newDigest": "sha256:3c8acd4934617f60dad7e4cc941faa064aa5a14da437dc156bdcad9d4a67bc4e",
"branchName": "renovate/node-16.x"
},
{
"bucket": "major",
"newVersion": "18.3.0",
"newValue": "18.3.0-slim",
"newMajor": 18,
"newMinor": 3,
"updateType": "major",
"newDigest": "sha256:0739e03851228cc1380f60e9dc14c192bd9d22d02eab364de609b6b8efb94174",
"branchName": "renovate/node-18.x"
},
上記で作成された PR をマージし、改めて Renovate を CLI から実行してみると、先ほどの non-major
アップデートと違い、major
アップデートとなっている。このことから、アップデート先のイメージは currentValue の書式、node:[0-9]+\.[0-9]+\.[0-9]-slim
を参考に、 該当する non-major
のバージョンがなければ、major
のそれを選定するように伺える。
ドライランでは、以下のように表示された。
"config": {
"dockerfile": [
{
"packageFile": "Dockerfile",
"deps": [
{
"depName": "node",
"currentValue": "16.15.1-slim",
"replaceString": "node:16.15.1-slim",
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
"datasource": "docker",
"depType": "stage",
"depIndex": 0,
"updates": [
{
"bucket": "major",
"newVersion": "18.3.0",
"newValue": "18.3.0-slim",
"newMajor": 18,
"newMinor": 3,
"updateType": "major",
"branchName": "renovate/node-18.x"
}
],
5-6.Presets で指定されているルールの確認場所
だいたい、以下で列挙されている。
https://docs.renovatebot.com/presets-config/
5-7.terraform の required_version と .terraform-version の更新を一つのグループにまとめたい
ポイントは、groupName
を同じにするということ。matchManagers
はそれぞれのパッケージやツールの Renovate の該当ページを参照して指定する。
// renovate.json5 一部抜粋
packageRules: [
{
groupName: "terraform-version",
// https://docs.renovatebot.com/modules/manager/terraform
matchManagers: ["terraform"],
matchDepTypes: ["required_version"],
},
{
groupName: "terraform-version",
// https://docs.renovatebot.com/modules/manager/terraform-version
matchManagers: ["terraform-version"]
}
]
x.困ったときに参照したいリンク集とひとことメモ
- はてなで使用しているRenovateの設定プリセットを公開しました - Hatena Developer Blog
automerge
の使い方として、メジャーアップデートは false とし、マイナーとパッチアップデートは true とするというところなど