※この記事は、2022 Speee Advent Calendar 19日目の記事です。 昨日の記事はこちら!
はじめに
はじめまして、イエウール事業部でエンジニアをしている22新卒の高島(@takatea_dayo)です。
本ブログでは、イエウールという規模の大きなRailsアプリケーションのアップデートを新卒がやってみて感じた辛さやそこから得た学びをまとめたいと思います。
イエウールのアプリケーションアップデートについて
イエウールは、家を売りたい売主様がオンライン上で不動産の一括査定依頼ができるサービスです。そんなイエウールは、約8年以上前に立ち上げられ、今ではかなり規模が大きいプロダクトとなっています。
イエウールでは、今でも多くの開発者が機能追加や改修を行っており、アプリケーションのコアはRailsで実装されています。
詳細は、さとーるさんの記事「混沌としたモノリシックRailsを手懐けるためにやったこと」にも記載されています。
tech.speee.jp
アップデートの概要として、今年の8月にリードエンジニアのなかじさんと、イエウールのアプリケーションをRuby2.7、Rails6.1へアップデートしました。特に、今回のアップデートでは、Ruby3.0やRails7.0へのアップデートを見据えた準備として、今後のアップデートで廃止になるような機能を使っている際に出力される「非推奨警告」も同時に排除することで、次回のアップデートをより行やすい状態にすることを目指しました。
アップデートに新卒がどう向き合ったか
実際にイエウールのアプリケーションアップデートを行ってみると、いくつかの辛いポイントがありました。そんなポイントをいくつかピックアップして、どのように向き合って乗り越えたのかを書いていきます。
① 失敗してはいけない!というプレッシャー
イエウールは前述の通り、かなり規模が大きくなっているプロダクトで、多くのエンドユーザーに現在もご利用いただいています。そのため、新卒で入社したばかりの私としては、「サービスを止めるような障害を起こしてはいけない」「開発者の開発速度を落としてはいけない」と過度にプレッシャーを感じてしまい、恐怖心をもちながらアップデートを行っていました。
このようなプレッシャーを乗り越えるためにも、アップデートを行う前には調査を行い、段階的なアップデートを行いました。
具体的には、アップデートによってどんな影響があるのかという点を漏れなく調査した後、「アップデート作業」と「エラーや非推奨警告に伴うコード修正作業」を分けてリリースすることで大きな障害なくアップデートを終えることができました。
プレッシャーに負けずにアップデートできた一番の成功要因としては、「漏れなく調査すること」を時間を区切った上で、やれるだけやり切ったことだと思っています。以下で少し具体例を挙げてやったことをご紹介します。
漏れなく調査すること
例えば、Rails6.0からRails6.1へのアップデートでは多くのデフォルト設定が変更になり、それらを有効にしていく作業にかなりの調査時間をかけました。
具体的には、Railsの変更差分を見て変更の意図までキャッチアップし、キャッチアップする中で知らなかった単語や機能はとことん調べました。時には、イエウールのエンドポイントのアクセスログを見に行き、本当に影響がないかまで調べました。
このような調査を、時間を区切ってしっかりやりきることが安心して、かつ大きな障害なくアップデートを終えられた要因なのだと思っています。
そして、調査したことは以下のように、社内で使っている情報共有ツールKibelaへアウトプットして資産として残し、他事業部にも横展開しました。
② アップデートで影響するコードの多さ
さとーるさんの記事(混沌としたモノリシックRailsを手懐けるためにやったこと)にも記載されているように、イエウールはモノリシックなアプリケーション構造をしており、イエウールサイトの画面や管理画面、請求書発行といった様々なドメインが一つのリポジトリに集約されています。
そのため、アップデートを行う際に影響するドメインが幅広く、アップデートに伴うエラーや非推奨警告が多く発生してしまい、その対応がとても大変でした。特に、管理画面や請求書発行というような今まで開発に関わってこなかったドメインの修正に対しても「コードの振る舞いは変わらないこと」を維持するためには、既存の仕様を理解しながら修正を行う必要がありました。
よって、シュッと修正してマージ、リリースするということができず、すべて修正するには数日かかりました。
幸い、イエウールのテストカバレッジは90%を超えており、テストがパスすればリリースしても問題ないと言える安心度の高い状態でした。
そのため、テストの実行はすべてCIで並列実行し、落ちたテストや出力された非推奨警告を、以下のようにIssueコメントへ列挙して一つずつ着実に修正して減らすことで、素早くコードの修正をしました。
③ RubyGemのアップデート
アップデート後のバージョン依存で多くのRubyGemをアップデートすることに加えて、非推奨警告対応のために多くのRubyGemをアップデートする必要がありました。
特に、開発環境や管理画面のみで利用しているようなRubyGemの多くは、バージョンのマイナーアップデートだけでなくメジャーアップデートも活発には行われていませんでした。
そのため、「バージョン依存でRubyGemのバージョンをあげたい」、「非推奨警告が対処されているRubyGemのバージョンへあげたい」というような小さな目的のために、破壊的な変更の有無やアプリケーションへの影響を時間をかけて調査してからアップデートする必要がありました。
こちらに関しては、上述したまでの対処と同じく、しっかりと影響を調査した上で一つずつ着実にRubyGemをアップデートすることで、開発者や営業チームの方の手を止めることなくスムーズにアップデートを進めることができました。
また、今回のアップデートで上げたすべてのRubyGemは、最新のバージョンに引き上げたため、次回のRubyGemアップデートでは、今回よりアップデートに対する負荷が軽減していると思います。
アップデートを通して得た学び
アップデートの大変さ
アップデート作業を始める前は、アップデートはテストを通してリリースするだけで終わるような単純作業だと思っていましたが、今回のアップデートを通して、時間や心理的なコストがとても高く、簡単にバージョンを上げられるものではないとわかりました。
特に、新卒エンジニアだけではなくとも実際に多くのエンドユーザーに使ってもらっているプロダクトのアップデートとなると、誰しもプレッシャーを感じると思います。そんなプレッシャーや不安は「いかに調査をやりきれるか」という部分で補っていくしかないんだと気づきました。
また、今回のアップデートでは、RubyやRails、RubyGemの変更差分を片っ端から見て影響範囲を調査することで、安心してアップデートを終えることができました。このような調査時間を減らすためにも、少しずつバージョンを上げていくことが大切だと実感しました。
アップデートの意義
アップデートは、エンドユーザーから遠いところで行うようなイメージがあり、コードのリファクタリングと同じように目に見えた成果が出にくいものだと思います。
しかしながら、アップデートは、アップデートしてすぐに大きな価値が生み出せなくとも、中長期的に見ると必ず価値が生まれてくるものだと思っています。
具体的には、アップデートすることによって、開発効率を上げたり、アプリケーションのパフォーマンスを高めたり、さらにはセキュリティのリスクを低くしたりと、とても大きな恩恵を受けることができます。
そのため、そうしたアップデートを継続的にしていくことが、エンドユーザーに少しでも早く多くの価値を届けるためには、とても大切だと知ることができました。
小さな改善の大切さ
上述した通り、アップデートの恩恵を十分に受けるためには、継続的にアップデートをしていく必要があります。
このような継続的なアップデートをしていくためには、少しでもアップデートにかかる時間を減らしたり、心理的負担を減らしてアップデートしやすい状態を維持することが大切です。
そのため、今回のアップデートで行ったような非推奨警告の修正やRubyGemのアップデートといった「小さな改善」を日常的に行うことがとても大切だと学びました。
そうしたアップデートしやすい状態を維持して負荷を減らすことができる仕組み作りとして以下を行いました。
アップデート負荷を下げるために行ったこと
今回のアップデートを通して、イエウールのような大きなプロダクトでは、非推奨警告が増えれば増えるほどアップデートの際に負担になり、継続的なアップデートを行うためのブロッカーとなり得ることを学びました。
しかしながら、実際には、アップデートに伴った非推奨警告の修正以外にも、今までずっと放置されていた非推奨警告も今回のアップデートの中で修正することが多々ありました。
そこで、イエウールのコアリポジトリでは非推奨警告を各開発者が気づいて日常的に直していけるように、「非推奨警告があったらCIを落としてマージできない」という仕組みを追加し、エラーと非推奨警告を同等の扱いにすることにしました。
かなりきつい制約なのですが、イエウールという大きなプロダクトを継続的にアップデートしていくためには必要なことだと思っています。そのため、このような意思決定を行った背景やメリット・デメリットを以下のような意思決定ドキュメントとしてまとめて、関係する開発者に共有した上で適用しました。
この仕組みが、次回のRuby3.0やRails7.0へのアップデート時に大きな役目を果たしてくれることを期待しています。
まとめ
本ブログでは、私が実際にイエウールという規模の大きなプロダクトのアップデートをしてみて感じたこと、そしてそこから得られた学びをまとめました。
特に、エンジニアとしてのスタンスとして、アップデートを継続的に行っていくためには、ボーイスカウトルールのように、非推奨警告のような「小さい改善」を日常的に繰り返していくことが大切だと知れたことがとてもよかったです。
そして、これからの開発でも大切なスタンスとして維持していきたいと思います。
最後に
Speeeでは一緒にサービス開発を推進してくれる仲間を大募集しています!こちらのFormよりカジュアル面談も気軽にお申し込みいただけます。
Speeeでは様々なポジションで募集中なので「どんなポジションがあるの?」と気になってくれてた方は、こちらをチェックしてみてください。
もちろんオープンポジション的に上記に限らず積極採用中です!