APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

ライブラリ自動更新にrenovateを導入してみる

renovate導入の話

みなさんはアプリケーションで使用しているライブラリ等の更新どうされていますか? 手動で行われていますか?それとも何か自動ツールを利用されていますか?

今回はそうしたライブラリ等の自動更新ツールであるrenovateを導入したときの 模様をお伝えしたいと思います。

といっても、インストールなどの方法は様々なところで紹介されているので省略し、導入過程でどういった状況になったかという ところをお伝えしたいと思います。

最初の実行

いくつかアプリケーションを開発していますが、まずは最初に Typescript / Node.js / NestJS を技術要素とするアプリケーションに 適用してみました。

まずは何も設定を行わず、単純にrenovateコマンドを実行しただけの状態です。 すると・・・出ました、たくさんのPull Requestが。初期状態だと以下のような動作をするようです。

  • PullRequestが発行するのみでマージは担当者が実施する(自動マージは行われない)
  • ライブラリ1つのバージョンアップに対して1つのPull Requestを発行する
  • 発行するPull Requestの上限はない
  • メジャーバージョンアップも対象となる

またもう1つ、対象がNodejsのプログラムだけかと思っていましたが、Azure Pipelineの YamlもPull Request発行の対象になるようです。(以下は内容サンプル)

設定を考える

やはり、何も考えずにOKというわけにはいかないようです。

Typescript / NodeJS / NestJS の更新

Typescript部分の更新は、いったん以下のようになってほしいと考えました。

  • Major updateは手動で行いたい。 大きな変更が伴うはずなので、手動で更新しコードの修正なども合わせて行う必要があるだろうという想定です。
  • Minor/Patchの更新はできるだけまとめたい。 基本的には1つのPull Requestにまとめて欲しい。今回はまだ導入当初でもあり、Minor/Patch両方が1つにまとまって良いと考えました。
  • package.jsonの ~^記載部分は更新しないで欲しい。 ここはどのように扱ったら良いだろうと考えましたが、いろいろ調べたところ renovateに rangeStrategyにupdate-lockfile という オプションがあることがわかったのでこれに合わせることにしました(~^指定のあるところは、範囲内の場合は更新しない。)
  • いったんPull Requestまでとしたい。 最初は動作を理解するために自動マージは行わず、少し実際に運用してからPatchだけは自動マージするなどに変更したい。

他細かい設定をいくつか追加しましたが、 上記を実現するための設定ファイル renovate.json5 は次のような内容になりました。

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  extends: [
    "config:base",
    ":disableMajorUpdates",
    ":timezone(Asia/Tokyo)",
    ":combinePatchMinorReleases",
    ":prHourlyLimitNone",
    ":prConcurrentLimit10",
    "group:recommended",
    "group:allNonMajor",
  ],
  packageRules: [
    {
      matchDepTypes: [ "dependencies", "devDependencies" ],
      groupName: "dependencies (non-major)",
      rangeStrategy: "update-lockfile"
    }
  ]
}

major updateを抑止するのが、 :disableMajorUpdates 、 minor/patchのPull Requestをひとつにまとめるのが :combinePatchMinorReleases 、対象をminor以下に限定するのが group:allNonMajor 、そして^~の書き換えを限定するのが rangeStrategy: "update-lockfile" の部分です。

最初に発行されたPull RequestをぜんぶCloseし、ブランチもすべて削除したのち、上記の設定を行ってあらためて renovate を実行すると次のような結果に。

package.jsonのほうはバージョンが固定されているもののみ更新されているのがわかります。

これで比較的シンプルになり、日々実行しても対応できる範囲になりそうです。

Azure Pipelineへの適用

上記の設定の状態だと、Azure Pipelineのほうも同様のPull Requestが発行されます。

今回こちらのほうはいったん対象外にしたいと思います。 (どちらかというと NodeToolsなどで指定する versionSpec のほうを対象にしてほしい・・・。これは今後の課題にしておきます)

{
  〜略〜
  packageRules: [
    {
      〜略〜
    },
    {
      matchDatasources: [ "azure-pipelines-tasks" ],
      groupName: "azure pipelines dependencies",
      enabled: false
    }
  ]

packageRuleに追加しました。これでいったんazure pipeline taskの更新は行われません。

初期導入後にやるべきこと

これでいったんは現実的な運用ができる状態になりました。といってもまだTypescript / Node.js / NestJS の環境向けのみ。 他にもAngularベースのSPAプログラムや、.NET 6/C# ベースのプログラムなどが控えています。 まずは今回と同様の設定を行います。

renovate等のライブラリ自動更新は、ツールを導入すればそれでOK、というものではありません。 それぞれの環境にあわせて、チェック対象とするか、対象とする場合はPullRequestに留めるのか、 それともマージまで自動的に行うのか。必要十分なテストはあるか? (テストがなければ、自動更新を行うこともできないと思います) それらはMajor/Minor/Patchのどのレベルで行うか。更新後の本番環境へのリリースはどういったフローで行うか。 さらに、多くのリポジトリ/プログラムを対象にしていくと設定内容の標準化なども必要になってくるでしょう。 renovate導入にあたっては、単にライブラリの自動更新にとどまらずその周辺に対してもさまざまな検討が必要になってきます。

今回のようにまずは簡単なレベルで導入し、次第にマージの自動化範囲の拡大やテスト、リリースフローの見直しなど 適用・自動化範囲を広げていくとよいと思います。

ということで、今回はここまで。次回があるとすれば、設定の標準化やAngular、NestJSにあわせた設定方法といった 内容になるのではと予想しています。

いつになるかわかりませんが、次回をご期待ください。