チームでちゃんとライブラリのアップデートできてる？継続的にライブラリアップデートを行うための仕組みについて

## はじめに

私のチームでは元々、テストもなく、ライブラリのアップデートもほとんど行われていないようなリポジトリがありました。
しかし、開発はそこそこ活発で、リリースも週1~2回の結構な頻度で行われるものでした。

最初は問題なかったのですが、日に日に依存関係が増え、
**リリース後にバグに気づいて切り戻しを行う**という体験を何度かしました。

rubyやrailsのversionも低く、ぼっち演算子(&)使いたいのになーとかこのgem入れたいけど対応してないなーという状態で
さすがにこれはしんどい！！ということで改革を始めました。

今回は、そんな状態のリポジトリをどう立て直していったか。
そして同じようなリポジトリが作られないために、どういう仕組を整備していったのかについて話していきます！

## そもそもどうして保守がなされない状況になってしまうのか？

根本的な原因を知らないことには、直してもまた同じ状況が作られかねません。
どうして保守がなされない状況になってしまうのでしょうか。
色々状況はあると思いますが、以下の枠に大抵はおさまるのではないでしょうか。

* 保守への一定工数が取れていない
    * 保守に対する評価のFBがない
    * 売上に直結する施策がメインで保守への割当がない
    * 保守への理解が得られない
    * 検証工数がかかりすぎる
* 知見がない
    * どのタイミングでやったらいいのか
    * アップデートしたときに、使えなくなったライブラリの代替となる手段が分からない
* 関心がない
    * 今までなんとかなってきている

幸い、自分のチームでは保守に対する理解は一定程度得られたため、工数を確保することへの反対は全くありませんでした。
ただ、メインの業務は進めてほしいというリクエストは当然あったので、限られた時間の中でどう保守していくか、が鍵でした。

### アップデートがされないことで起こる問題
アップデートを進めないことで、下記のような問題が起こりえます。

* セキュリティリスクの増加
* 新機能や関連ライブラリなどが使えない
    * 効率の良い開発ができなくなる。
    * より高パフォーマンスな実装ができない。

また、アップデートが遅れると差分がどんどん大きくなり、よりアップデートしづらくなる悪循環が起きていきます。

このような状況を避けていくために、この半期行ったことを記事にまとめました。

より詳しい内容については下記記事がまとめられていると思います。

https://qiita.com/autotaker1984/items/a3091772dbb0fb91473d


### 結果
いきなり結果ですが、元々ほとんどアップデートされておらず、0件だったところから、
数ヶ月でかなりの量のライブラリアップデートが行われました。

波はありますが、継続的にライブラリのアップデートが行われています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/f6a81607-cf3a-f99e-fcd1-bb932f720bd5.png)

※ mergeしたMR数を集計。

初期の頃は、merge数が多くなっていますが、理由はrenovateの設定によるものが大きいです。
下記2点が大きな理由です。

* MRをパッチバージョン単位のMRにまとめてアップデートをしていたため。
    * 今はパッチバージョン、マイナーバージョンは一つのMRで作成。メジャーバージョンは別MRで作成。
* 初期の導入時はバージョン差分が大きく、マイナーバージョン、メジャーバージョンのアップデートが多かったため。

## 取り組んだこと

### アップデートの自動化
継続的にやるためには、少しでも楽にできるような仕組み作りが必要です。
[renovate](https://github.com/renovatebot/renovate)と[gitlabci-bundle-update-mr](https://rubygems.org/gems/gitlabci-bundle-update-mr/versions/1.1.1?locale=ja)を用いて、下記の自動化を行えるようにしました。

* MRの自動作成
* アサインの自動化

renovateを有効化すると下記のような形でダッシュボードが作られて、どんなアップデートが必要なのかがひと目でわかるようになります。
githubであればrenovate.jsonの用意と[renovate](https://github.com/apps/renovate)のGitHub Appsを有効化するだけで導入できます。

![スクリーンショット 2023-08-03 15.19.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/fd93dd04-eebc-e4c8-e918-90fbfab44e17.png)


MRも下記のように自動生成され、changesのリンクがあるので、どんな変更があったかをすぐ見れるようになります。

![スクリーンショット 2023-08-03 15.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/6d3f2383-f68c-6c9a-7599-d59f572bed05.png)


* renovateとgitlabci-bundle-update-mrを定期実行するために、gitlab-ciに組み込んで、スケジューリングすることで実現しています。
![update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/c1f4658d-7af2-fd03-92b4-522416cde5a2.png)




#### renovateの設定について
基本的には[renovateのベース](https://github.com/renovatebot/presets/blob/dda2282e5a53982daea09489d622eedc174243e2/packages/renovate-config-config/package.json#L16-L36)の設定を利用しています。
独自でカスタマイズしているのは、
メジャーバージョンでないものは一つのMRにまとめるようにしていることと、
特定のパッケージマネージャーに絞ってrenovateを有効化し、
assigneesとassigneesSampleSizeを設定することでアサインの自動化をしていることです。


```renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base",
    "group:allNonMajor"
  ],
  "enabledManagers": [
    "nodenv",
    "npm"
  ],
  "assignees": [
    "hoge.tarou"
  ],
  "assigneesSampleSize": 1
}
```

### 必要性の浸透
仕組みを導入しただけだと、まだチーム間でアップデートを進めていこうという動きにはなりません。
そのため、必要性の浸透と継続的な議論が行われるようにするため、週１回の定例MTGを設けました。

MTGの枠組みは下記のような形です。
``` 
* アップデートした内容の共有
    * 詰まったポイント
    * 機能の共有
    * 変更内容の共有
* renovate ダッシュボードの確認
    * 優先して上げたほうがよいライブラリの確認
    * まだ上げないほうがいいライブラリの確認
``` 

この会を通して、徐々にみんなでライブラリのアップデートをしていくという流れができるようになりました。

### 優先度を付ける
しばらく定例MTGを続けてみて、
全部を毎度アップデートするのはなかなか時間が取れないということで、
やらなくなるリポジトリというのがでてくるようになりました。

このままやらないリポジトリがどんどん増えていってしまうと、
また保守がされていない状態に戻ってしまうことを懸念して、優先度をつけるようにしました。

最初はエンジニア間の合意で優先度を付けていましたが、基準が曖昧で、
見直すきっかけが作れないと考えたため、
基準を作成し、どの頻度で手を付けていくかを明文化しました。

下記のようなライブラリ管理ダッシュボードをスプレッドシートで作成し、管理するようにしました。

![スクリーンショット 2023-08-03 15.31.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/2921b9e5-90ce-c016-940b-93583c23d525.png)

* 重要度別に振り分けし、アップデート見直しの期間を定めた
    * A群: 現状、積極的に開発が行われているもの
    * B群: 将来的に開発が活発化する / 開発は停滞しているが売上規模が大きいもの
    * C群: 現状維持のもの
    * D群: 社内ツール

A~D群に振り分けたものを各シートに自動で反映されるようにして、週1の定例MTGでアップデートできたかを振り返るようにしています。

![スクリーンショット 2023-08-03 15.32.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224825/91656bed-a107-283f-9295-baa0d51e38ca.png)


### その他雑感

* renovateを導入したことで地味に良かったこと
    * パートナーさんへの依頼がしやすくなった。MRを渡して検証をお願いすれば良くなった。
    * 技術動向を追う頻度が増えた
* ライブラリ管理ダッシュボードを作ることで起きた副作用
    * リポジトリ自体を見直すきっかけになった。
    * 納得感を持ってアップデートを進められるようになった。

### 終わりに

最初はなかなかうまく行かない部分もありましたが、仕組みができたことで
継続的にアップデートがされ、古すぎるリポジトリというのはだいぶ減ってきました。
すぐには効果が見えづらい部分ではありますが、継続的に進めていければ良いと考えています。

誰かの参考になればと思い、投稿しました。
もし質問等あればお答えしますので、お気軽にどうぞ。

## 関連記事
https://zenn.dev/ryo_kawamata/articles/6f878891cf0c51

https://zenn.dev/yuitosato/articles/cad5ab93e852ab