MENU

Renovate scheduleとgroupingとrangeStrategyと(on Github Actions)

renovateを、いい感じに実践導入するための布石として理解を深めるべく、
ちょこちょこ記事を書いてきた。

Renovate(onboarding)
Renovateをgithub Actionsで実行してみる

そのシリーズの第3弾

今回は以下を設定してみる

  • schedule
  • grouping
  • rangeStrategy
目次

scheduleとgroupingとrangeStrategyについて

schedule

公式

renovateがpull requestを作成する時間帯を規定するための設定。

デフォルトの設定値は["at any time"]となっており、これだと常時renovateによるpull requestの作成が可能となり、
場合によってはノイズとなるため、scheduleを設定して制御する。

scheduleの構文としては、

  • Cron syntax
  • Later syntax

のいずれかを用いる。

後者は見慣れないので、どうやって設定するのかなと思ったが、
公式がSchedule Presetを用意しているので、ここを見て、理解を深めつつ、借用するのが良さそう。

例示すると、

{
  "schedule": ["after 10pm and before 5am every weekday", "every weekend"]
}

このように書いた場合、以下期間にrenovateによるpull requestが作成可能となる。

  • 平日10pm〜5am の間
  • 週末は常時

期間を指定する、というのと、

複数書いた場合には、or 条件 として採用される、というのがミソですね。

ちなみに、

timezone: Asia/Tokyoを同時に設定しないと、scheduleを判定する上でのtimezoneとして、UTCが使われてしまうため、
scheduleを設定する場合には、必ずtimezoneを設定する。

grouping

公式

デフォルトでは、ライブラリのバージョン更新ごとにpull requestが作成されますが、

マイナーのバージョンアップはまとめたい!等、

扱いやすいように、pull requestをグルーピングするための設定。

グルーピングするためには、以下のような設定が最低限必要。

{
  // パッケージ毎に適用したい設定を書く
  "packageRules": [
    {
      // パッチとマイナーの更新をまとめる
      "matchUpdateTypes": ["patch", "minor"],
      // グループネーム
      "groupName": "devDependencies (non-major)"
    }
  ]
}

packageRulesの配下に、各種設定をまとめていきますが、一番は、

groupNameを設定することで、グルーピングされる」という点ですね。

rangeStrategy

公式

この設定がちょっとややこしい。

まずは、設定候補値とそれぞれの仕様を確認する。

- auto: renovateに一任する(デフォルトの設定値)
※ 詳細を以下に記載する

- pin: 範囲を正確なバージョンに変換
例: ^1.0.0 -> 1.1.0

- bump: 新しいバージョンが既存の範囲を満たしている場合でも、その範囲をバンプする 
例: ^1.0.0 -> ^1.1.0

- replace: 新しいバージョンが範囲外にある場合は、範囲を新しいものに置き換え、そうでない場合は何も更新しない。
例: ^1.0.0 -> ^2.0.0

- widen: 範囲を新しいものに広げる。
例:  ^1.0.0 -> ^1.0.0 || ^2.0.0

- update-lockfile: 範囲内の更新が利用可能な場合はロックファイルを更新し、そうでない場合は範囲外の更新を置き換える。
今のところ bundler, cargo, composer, npm, yarn, pnpm, terraform, poetry で動作。

- in-range-only: 範囲内の更新があったときにロックファイルを更新し、パッケージファイルの更新は無視する。

「rangeStrategy:auto」の仕様をさらに引用すると、 以下の優先順位で更新内容が決まるらしい。

1. `peerDependencies`を広げる

2. `widen`の挙動:
既存の範囲がすでに `^1.0.0 || ^2.0.0`のような "or" 演算子で終わっている場合、 `^1.0.0 || ^2.0.0 || ^3.0.0` に広げる。

3. `replace`の挙動
更新が既存の範囲外であれば、Renovateはその範囲を置き換える。つまり、`^2.0.0` は `^3.0.0` に置き換えられます。

4. `update-lockfile`の挙動:
更新が範囲内であれば、Renovateは新しい正確なバージョンでロックファイルを更新します。

まぁ、中々これを読んだだけだと、理解しきれないところもあるので、

好ましい設定は、ある程度実践で運用していく中で掴んでいければ良いかな。

今回は、bump(新しいバージョンが既存の範囲を満たしている場合でも、その範囲をバンプする )を採用して、挙動を確認していきます。

最終的な設定

renovateを実行用に、以下のファイルを作成した。

  • .github/workflows/renovate.yml
  • .github/renovate.json

.github/workflows/renovate.yml

name: Renovate

on:
  schedule:
    - cron: '0/15 * * * *'
  workflow_dispatch:

jobs:

  renovate:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4.1.1

      - name: Self-hosted Renovate
        uses: renovatebot/github-action@v40.0.3
        with:
          token: ${{ secrets.RENOVATE_TOKEN}}
        env:
          LOG_LEVEL: 'debug'
          RENOVATE_REPOSITORIES: '***'
          RENOVATE_USERNAME: 'renovate[bot]'
          RENOVATE_PLATFORM: 'github'

「デフォルトブランチをチェックアウトしてrenovateを実行する」という
必要最低限のworkflow。

.github/renovate.json

{
    "$schema": "https://docs.renovatebot.com/renovate-schema.json",
    "extends": [
        "config:recommended"
    ],
    "branchPrefix": "renovate/",
    "labels": [
        "renovate"
    ],
    "schedule": [
        "after 7pm every weekday",
        "before 5am every weekday",
        "every weekend"
    ],
    "timezone": "Asia/Tokyo",
    "prHourlyLimit": 0,
    "rangeStrategy": "bump",
    "packageRules": [
        {
            "matchUpdateTypes": [
                "major"
            ],
            "enabled": false
        },
        {
            "groupName": "all non-major dependencies",
            "groupSlug": "all-minor-patch",
            "matchPackagePatterns": [
                "*"
            ],
            "matchUpdateTypes": [
                "minor",
                "patch"
            ]
        }
    ]
}

今回の記事に関連するポイントだけ、かいつまんで説明。

  • schedule
    • 「平日7pm〜5amの間」と「週末」のみ、pull requestが作成されるように。
  • timezone
    • Asia/Tokyo
    • scheduleの判定がデフォルトのUTCではなく、Asia/Tokyoで実行されるように。
  • rangeStrategy
    • bump:新しいバージョンが既存の範囲を満たしている場合でも、その範囲をバンプする
  • packageRules
    • major updateのpull requestは作成しない
    • minor、patch updateのpull requestは一つにまとめる

動作確認

上記の設定をした上で、しばらく待ってみると…
Github actionsのworkflowが発火して、renovateが実行された結果、
pull requestが作成された!!!

schedule

Configuration > Scheduleを見ると、想定通り設定されていることが分かる。

grouping

想定通り、minorとpatchのupdateが一つにまとめられたpull requestが作成されている。

rangeStrategy

bump を設定したので、その辺りの挙動を確認すべく、npm周りのupdateを見てみる。

例えばaxiosは、main ブランチ > package-lock.jsonを見ると、

↓ の通り、現状ver 1.6.7 がinstall されていることが分かる。

つまり、
package.json > axios > ^1.6.4 というversionの指定範囲に従って、
package-lock.jsonの作成時点で最新のversionであった1.6.7 がinstallされている、という状況。

これは、bump の設定でいう所の、

新しいバージョンが既存の範囲を満たしている場合でも、その範囲をバンプする

の状況に当てはまっていることになるので、範囲をbumpする(^1.6.4^1.6.7)挙動になっている、と考えられる。

rangeStrategy:bump を指定していなければ、

^1.6.4^1.6.7

この更新はスルーされる(はず)

詰まったポイント

1. scheduleを設定しただけでは、renovateは自動実行されない

Github Actionsでrenovateを実行する場合、
renovate.jsonにscheduleだけ設定すれば、scheduleに沿ってrenovate自動実行されると思っていたのですが、そんなことはなかったです。

Github Actionsのworkflowファイルでcronを指定する等、別途定期実行する仕組みは入れる必要がある模様。

その辺り、公式document見ても特に記載は無さそうで、
ググってみても、その辺りに言及している or この点で詰まっている先人たちはいなそうで…(そりゃそう?)

最初、Scheduleだけ設定して
「なんで動かんのや…?」
とヤキモキしていました。

最終的に、以下のような設定になったわけですが、

  • .github/workflows/renovate.yml
on:
  schedule:
    - cron: '0/15 * * * *' // 15分毎にrenovateを実行するworkflowが実行される
  • .github/renovate.json
    "schedule": [
        "after 7pm every weekday",
        "before 5am every weekday",
        "every weekend"
    ]

つまり、

  1. workflowファイルに記載したcronにより、renovateが15分毎に実行される
  2. 「1.」の時、実行日時がscheduleの中のいずれかに当てはまれば、renovateによるpull requestが作成される

という動きになっています。

実際に、cronでのrenovate workflow実行時のログを見てみると、、、

上記のように、
「scheduleの範囲外なので、PRの作成をスキップします」というログが載っています。

そもそも、
scheduleも範囲の場合のみrenovateが実行される、と勘違いしていました。

2. preset(config:best-practice)に頼りすぎた

renovateにより、best practiceとして、
preset(config:best-practice)が用意されています。

公式

最終的には、
renovate.jsonでは、config:recommended をextendすることにしたのですが、
最初は、上記のconfig:best-practice を使っていました。

で、後者をextendした場合の設定は以下の通りとなります。

{
  "configMigration": true,
  "extends": [
    "config:recommended",
    "docker:pinDigests",
    "helpers:pinGitHubActionDigests",
    ":pinDevDependencies"
  ]
}

docker:pinDigests
 :pinDevDependencies

この辺の設定をすることで、dockerと各パッケージマネージャーで管理しているライブラリの依存関係が固定されるようになるので、
この設定をした上で、renovateを実行した際には、以下のようなpull requestが作成されていました。

これだと望んでいる仕様ではなかったのですが、
config:best-practice の設定を把握していなかった当初は、なぜこのようなprが意図せず作成されるのか、良く分からず、途方に暮れました。

なので、最終的に使うことにした、
config:recommended にせよ、config:best-practice にせよ、
具体的にどのような設定がされるのか把握しないままに、安易に採用するべきではなかったな、と感じました。

best-practice を盲信しないことですね。

感想

auro merge関連の設定など、やりたいことがもっとあるので、
ちょこちょこ仕様の把握、進めていきたいと思います。

しかし、やりたい設定を探そうとすると、
renovateの設定項目多すぎて、複雑で、動作確認にもだいぶ時間かかってしまったのですが、
自分が詰まっているところで、同様に詰まっている先人たちの記事を中々見かけないのですが…
自分のレベル低すぎ…?

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次