2019の10日目の記事です。この記事の概要Webフロント開発をしている際に、npmライブラリのマイグレーションって結構コストかかるので自動化したいよねって動機の元、そのためのツールとしてDependabotとかRenovateとかあるけど、どっち使うのが良さそうかなという検討をしました。npmライブラリの更新という側面からの記事のため、他の言語やパッケージ管理システムからの側面についての検討はされていないことをご留意ください。時間に追われて書きなぐった内容になっていて後で書き直すかもしれませんがご了承いただければと思います。registryを使っている自分たちの環境ではRenovateが良さそうでした。その理由としては以下の通りです。Requestのグルーピングがしやすいつまり、機能的にRenovateの方が充実していてRenovateの方がやりたいことがすぐ実現できる、というのが理由です。この結論に至るまでの話を以下長々と書いていきます。ライブラリ自動更新のために求められていたこと開発環境や自分たちで作っているライブラリなどの構成、npmレジストリ等の都合から以下のことができる必要がありました。そのため、以下の項目を満たすことを条件としています。registryのAPIを利用できること指定した条件にマッチするライブラリだけを更新できること(ホワイトリストあるいはブラックリストが指定できる)モノレポなど複数のライブラリが一つのリポジトリで管理されているものもうまくバージョンを揃えて更新できることこの4つのうち、最後のものについては少々イメージしにくいかもしれないので補足します。内製のライブラリが多く、ライブラリごとにリポジトリを作っていると管理が大変になるので、似たようなもの、一つの機能を実現する際に同時に変更する必要があるものを一つのリポジトリにしてモノレポとして扱っています。APIクライアント系APIクライアントはシステムごとにAPIクライアントを作るため、システム数分のクライアントができます。いうものも存在し、そのコードに手が入るときは他のクライアントも影響を受ける場合があります。ディレクトリ構造としては以下のようなイメージです。Componentなど、ある機能を実装するときにはだいたい一緒に変更する必要があるコード群を一つのモノレポにしています。一見すると役割が別のものが一緒になっていて気持ち悪さを感じますが、役割に応じて作業者が変わるわけではないので、別リポジトリになっていると個々のリポジトリで作業してpublishして取り込んで、といった流れは作業効率がとても悪くなるのでモノレポにしています。ディレクトリ構造としては以下のようなイメージです。前述のようないくつかのモノレポが存在し、各アプリケーションはそれらのパッケージをバージョンの齟齬なく上げる必要があります。相当するのはview-component@2.0.2であったりすることもあり(これは元は別リポジトリだった歴史的経緯もあり)、全部同じバージョンでいいという状態ではありませんでした。Request(以下PRと略)が作られても、CIが通らず実装内容の問題なのか、view-componentと分かれてPRが出ているだけで内容自体に問題はないのかわからずマージできないという問題がありました。api-clientsは中のパッケージがほぼ独立なので個別のPRに分けられていてもそんなに問題はありませんが、ベースとなるclient-kitに手が入る場合は依存関係が発生してしまうのと、一気に複数のクライアントのバージョンが上がった際、個別にPRが出てCIのマシンパワーが自動更新系のPRで吸われてしまう、という問題を避けたい事情もありました。そのため、基本的にモノレポ内のパッケージは1つのPRにまとめて更新する必要がありました。Renovate両ツールを使ってみてどうだったかという話をします。Depentabot先に使ってみたのはDependabotでした。いうのもwebpackがdependabotを使ってマイグレーションをしていたので、それに倣ってやってみようというわりと軽いノリで試しました。実装をベースとする使い方をしました。自分たち用に以下のようなカスタマイズすることで利用しています。デフォルトブランチの指定を環境変数から渡せるようにするArtifactoryのトークンやregistryのURLを環境変数から渡せるようにする更新対象のパッケージをホワイトリスト管理できるようにする特に3つ目に関しては、依存しているライブラリすべてを対象にするとPRの数が多くなり管理しきれなくなってしまうので、運用が慣れるまでは更新頻度が高い内製ライブラリに絞るようにしています。所感Dependabotだと1つのパッケージにつき1つのPRが作られるので、前述のモノレポ系のパッケージ更新がうまくできないという問題にぶつかりました。いった簡易的な記述しかされないのも何が変わったのかよくわからない、という問題もありました(これはgithub.comではないからかと思っています)。前者の問題に関して、以下2点のdependabot-script改修を検討しました。指定したパッケージを1つにまとめてPRを投げる指定したパッケージは別のブランチにPRを向ける指定したパッケージを1つにまとめてPRを投げるdependabot-coreのPRを作る部分の実装を見ると、1つのPRに複数のパッケージを混ぜるような設計にはなっていないように見受けられました。内部の実装もDIしやすいようには作られておらず、利用する側でちょっとカスタマイズするといったことも困難でした。そのためこの方法は検討を打ち切りました。指定したパッケージは別のブランチにPRを向ける例えばデフォルトブランチはdevelopブランチで、通常の更新はdevelopブランチへPRを投げるが、モノレポ系パッケージの更新は別途ブランチを用意してそちらにPRを投げ、そのブランチである程度まとめてしまってからdevelopに対してPRを投げなおす、という方針を検討しました。その場合、別途作ったブランチとdevelopブランチでコンフリクトが起こってしまう場合に自動で解消するのが困難(あるいはそれ用の実装をしなければならない)だったり、パッケージごとにベースブランチを分けられるようにするという実装は元のdependabot-scriptでは想定されておらず、フルスクラッチで書き直すレベルで手を加えないといけないといけないことがわかりました。なるとこの方法もコストが高く、この段階からDependabotの使いづらさにつらみを感じるようになってきました。結果的にはこのあたりでDependabotに見切りをつけてRenovateを試し、Renovateの方が良さそうという結論になってしまったためそれ以上Dependabotに深入りしないままになってしまいましたが、より良い使い方があるという知見のある方がいらっしゃいましたら、ぜひ教えていただければと思います。Renovate順番的にはDependabotの次に試したのでDependabotのつらいところが色々解消された印象が強く、ややバイアスがかかっている感じは否めませんが、設定が細かくできてとても使いやすかったです。よってPRのグループ設定ができるのが良いです。サンプルとしてアプリケーション側で入れている設定を以下に示します。"@nicolive:registry=https://****/****/\n//****/****/:_auth=${NPM_TOKEN}"}これにより、以下のことが苦も無く行えるようになりました。よって制御できるものです。グルーピングや対象パッケージを絞れるといっても日々業務中に容赦なくRenovateからバシバシPRが飛んでくる(PRが作られるとSlackに通知が来る)のがプレッシャーに感じるメンバーも少なくなかったため、量をコントロールできることも地味に有益な機能と感じました。気になったところRenovateで唯一気になったのは、各リポジトリの設定でnpmrcを全部入れてあげないといけないことでした。トークン類は基本的にはリポジトリに含めたくないため、リポジトリ内の.npmrcにはregistryのURLのみ記載し認証情報は各自ローカルマシンやCIサーバの特定のもののみに含めるという運用ですが、Renovateにはまだ各所に配置したnpmrcの内容をマージすることはまだできないらしく、仕方なくトークンをencryptして乗せるという運用になっています。冒頭で書きましたが、結論としてはDependabotよりRenovateの方が使いやすい、という結論に至りました。Depentabotもgithubマーケットプレイス版ならある程度は使えそうな気がしますが、込み入った運用になっている内製ライブラリの更新には向いてなさそうでした。今後の発展に期待したいと思います。Renovateは設定も細かくでき痒い所にも手が届く感じがとてもよかったです。.npmrcのマージだけはできるようになって欲しいですが気長に待つことにします。本記事に関して間違い、ご指摘などありましたらコメントいただけますと幸いです。upLoginユーザーは見つかりませんでした。