💎

Railsのバージョンアップを行う上で悩んだこと

2023/04/27に公開

業務でRailsのバージョンアップ作業を行ったので参考記事やポイント、悩んだことを備忘録としてまとめる。悩んだことや反省点も合わせてメモ。
バージョンアップを行う予定がある方々は参考にしていただければ。

参考にした記事

Railsバージョンアップ作業にあたって本当にお世話になった記事を整理。公式のアップグレードガイドだけでは作業に入れなかったので、本当にありがたかった。

Railsガイド_Rails アップグレードガイド
実際に作業に移るためには少し抽象的に感じた。

永久保存版!?伊藤さん式・Railsアプリのアップグレード手順
最高。ほとんどこれに沿って進めた。

エンジニア1年生が行うGemアップデート手順
Gemのバージョンアップに関してはこちらを参考。特に「手順2. 対象のGemを調査」が参考になった。

【Ruby】 gemの仕組みを図解形式で学ぼう
Ruby: GemfileとGemfile.lock究極ガイド(翻訳)
そもそもGemfile周りの知識がなく、標準ライブラリと外部ライブラリの境界線を把握できていなかったため、参考になった。

個人的に重要なポイント

specのカバー率の向上&高速化(超大切)

バージョンアップにおいて最も怖いのは作業前後で動作が変わること。それを防ぐために最も効果的なのはspecである。バージョンアップ作業において、手動確認は毎回してられないため、何回もspecを回す。specにかかる時間がバージョンアップ作業の半分以上を占めることになりかねない。超大事。

GemがRubyのバージョンをサポートしているか

マイナーなGemだとメンテが止まってしまい、最新のRubyをサポートしていないことがある。
スター数が多くても止まっていることもあるので要注意。筆者は作業途中でGitHubのスター数が2000以上のgemのメンテが止まっていることに気づき、大ダメージを受けた。
ちなみにどのバージョンをサポートしているかはtravis.ymlやcircleciなど自動テストのymlをチェックすれば大体記載されている。

悩んだことなど

どのタイミングでテストを行うか

specに1時間以上かかるサービスだったので、毎回は流してはいられない。どのタイミングで回すべきかは少し悩んだ。今回はある程度工程に余裕があったため、大きな変更を伴うGemのバージョンアップを行った時は必ず全件パスを確認した。時間に余裕がない時はどうすべきか、、。
test groupとdevelop groupのgemは基本一括アップするので、完了後は迷いなくspecを回すべき。default groupのgemは一つ一つ上げて必要な箇所だけ動作確認する。そうなるとgemをいくつアップしたタイミングでspecを回すべきか悩む。大方挙げてしまった後だと面倒なことになりかねない。
specの重さが身に沁みた。。

Change Logsをどこまで見るか

確実にバグを避けて進むため、基本的には全てのGemのChange Logsをチェックし、Breaking Changesがあるかを確認してから進める。しかしサービスの規模や複雑さによってインストールされているGemは多く、細かな変更点まで全てを追うのは不可能と言える。それでも時間が許す限りは追うが、やはりどこかで妥協しなければならず、今回行った業務ではBreaking Changesと主要なGemの確認までにとどまった。
ここはバグを孕みやすいGemを把握しておくなど、経験がものをいう世界だと感じた。

Gemをどこまでバージョンアップするか

Breaking Changesを含んでいたり、依存関係でバージョンアップできなかったりする場合は別で対応する、という選択肢を取りやすい。それ以外の場合は判断が難しい。機能追加やruby等のバージョンのサポート対象の変更だけならアップデートで問題ないと思われるが、使っているかわからない機能の削除や修正が行われている場合は判断し切れない。動作確認してもバグを孕んでいる可能性を否定できないため。

反省点

specの不備のチェック

今回はバージョンアップ対象のGemが大量にあり、バージョンの上げ幅が大きいものが多かったため、specの増強までは頭と手が回らなかった。Gemのバージョンアップにおいて最も怖いのは挙動が変わることであるため、specのカバレッジは気にすべき。次回以降、なんなら常にspecのカバー率は気にしておくべき。

終わりに

バージョンアップ作業の中で度々gemのソースを調査したので、だいぶ読めるようになったし自信がついた。
特にFaradayやHerのソースはかなり細部まで追ったのでまた今度記事にしたい。

Discussion