Railsバージョンアップに学ぶフレームワークアップデートの進め方

自己紹介

お久しぶりです。ジモティーで2020年4月からサーバサイドエンジニアをしている水上と申します。 早いもので入社3年目となり、日々案件開発と格闘する日々を送っております。

まえがき

入社3年目となり、大きめの案件開発に携わることも増えてきたので、少し前に実施したRailsのバージョンアップについて記載致します。

Rails バージョンアップ

今回のバージョンアップ前の弊社のRailsは5.2.6でした。 最近Rails 7が発表され5.2系のサポートが今年6月までで切れてしまうとのことで今回のアップデートを実施した運びとなります。

作業内容

  1. バージョンアップ先選定&バージョンアップ
  2. アップデート後Railsが起動する状態にする
  3. raill consoleの起動に成功したらCIを完走させる
  4. CIでは賄いきれない箇所があるので、手動で動作テストを行う
  5. レビュー
  6. 他部署連携テスト
  7. リリース

以下、トピックごとに今回行った詳細を記載します。

1.バージョンアップ先選定

今回はバージョンアップ手順のドキュメントが充実していた5系から6および6系から6.1の最新である6.1.4をターゲットとしました。 RubyのバージョンがボトルネックとなりRails7へのアップデートは見送りになりました。 - Gemfileを修正しつつbundle update - bin/rails app:update 上記2点を実施

2.アップデート後Railsが起動する状態にする

今回の最初の山場がここでした。

Rails6からAutoload方式が変わって、新しくZeitwerkが推奨となりました。バージョンアップ前の記載はClassicモードとして利用可能ですが、非推奨になりました。 そのため上記に対応するのか、非推奨警告を出したままclassicで行くのかの調査などに時間がかかりました。 新Autoload方式に対応するために修正すべきファイルが多いため、今回は対応外とし、classicのままで次回のバージョンアップ時にZeitwerk対応を行う予定です。

3.rails consoleの起動に成功したらCIを完走させる

大きく時間がかかった箇所その2でした。

CIは開始するようになったものの初期完走時でエラー数は1800ほど発生しており、すべての修正に辟易しながらも中身を見てみると同じエラーで失敗しているものが多く、パターンを覚えて適宜対応しました。

その中でも、database cleanerとfeature testの相性が悪く、specファイル内で正しくcreateしているにも関わらず対象テストの実施時にdatabase cleanerが動作してしまい、対象テストに必要なデータまで削除されてしまう事態が発生していました。 factory_botのアップデートによりbuild及びcreateの挙動が変わり、以前までの記載だとdatabase cleanerが動き出してしまう状態に陥っていたようでしたので - buildの箇所をcreateで書き直し - 明示的に.saveを行う

等対処していたところ結果として、上記対応は不必要であり

FactoryBot.use_parent_strategy

の設定を行うことで諸々の挙動が改善しました。 結果として、既存の書き方を踏襲したままアップデートすることができました。

アップデートにおける開発体験は極力変えたくなかったので上記対応にて体験を変えずにアップデートできたのは良かったです。

4.CIでは賄いきれない箇所があるので、手動で動作テストを行う

手動テストを行ったところ、Rails 5->6へのアップデートの際、デフォルトのままだとCookieの互換性が無く、ログイン状態がリセットされてしまう問題が露見しました。 原因は2つ有り - ENV[“SECRET_KEY_BASE”]が未設定だった - Rails6からCookieにメタデータが埋め込まれるようになったため、後方互換性が失われた

ENV[“SECRET_KEY_BASE”]が未設定だった

に関してはRails5のメインブランチに対して、secret_key_baseをAWS Parameter Storeに保存しておき、そこから呼び出す様に変更を適応

Rails6からCookieにメタデータが埋め込まれるようになったため、後方互換性が失われた

に関しては

Rails.application.config.action_dispatch.use_cookies_with_metadata = false

を設定することで対応できました。

他部署へのテスト依頼のためのテストケース作成もこのタイミングで作成しました。 ジモティーというサービス上テストすべき画面が非常に多く、自身の手動テストや、テストケースの作成が大変でした。 同じ画面でも複数のパターン(ログイン済みか非ログイン状態か等)があるため、漏れがないようにしなければ障害発生は避けられません。

5.レビュー

他の作業に比べると大きな時間はかかりませんでしたが、レビュアーがレビューしやすいように工夫はしてくべきだったと悔やんでおります。 コミットの区切り方やメッセージの内容等をきちんと精査し、レビュアーが見やすい状態にしておくことを今後意識します。 また、メソッド名の変更等、使用箇所が多いものの命名変更はレビュー時のノイズとなるため、単なる命名変更は別PRとして切り出しておくとスムーズでした。

6.他部署連携テスト

部署ごとにテストケースの確認と実施したほうがよいテストは無いかを確認してもらいながらテストを実施しました。 CSチーム、アプリチー厶、それぞれの観点からテストケースを拡充して頂き、結果としては良いテストケースが作成できました。

7.リリース

本来の予定ではカナリアリリースを行う予定でありましたが、CSRFトークンの変更等の後方互換性の無い変更が含まれていた事により、Rails5<->Rails 6のPOSTができない問題等があり一斉リリースとなりました。そのため、テストケースの充実が更に重要でした。

おわりに

今回の様な大規模な開発を行うことで業務や、Railsについての知識がさらに充実しました。開発体験も大きく変えずにリリースまで完了できて非常に良かったです。 次回以降にアップデートを行う際は今回学習した点を踏まえてよりスマートにアップデートを行いたいです。 Rails7へのアップデート担当が僕になるとは限らないため、今回の知見をドキュメントとして残しておくことで次回以降に役立てればいいなと思います。

また、弊社ではジモティーを更に成長させる為に一緒に取り組んでいただけるエンジニアを募集しています。 頼りになる先輩方と一緒に開発できればと思います。 (僕も頼りがいのある先輩の一員になれるよう精進中です) もし少しでも気になればお気軽にご応募ください。


弊社では一緒にプロダクトを改善していただける仲間を探しています!

こちらでお気軽にお声がけください!

ネイティブアプリエンジニアの採用って難しいですよね。。。

ジモティーのウェブチームについてお話ししたいです