自転車とプログラミング

自転車メーカーに勤める会社員がプログラミングを学ぶ中で感じたことを書きます。最近サービス作りました。

Rails appをアップグレードしました

こんにちは、Watanabeです。

自作のRails appでアップグレードが溜まっていたので対応したことを記事にしました。

環境

サービスページはこちら

作業前に考えておくこと

前提条件

(Rails アップグレードガイド)https://railsguides.jp/upgrading_ruby_on_rails.htmlによるとアップグレードに着手する前に確認しておいたほうがいい事項がある。

  • アップグレードする目的
  • アップグレードによって改修が必要になる既存コードの量
  • アップグレード作業とコード改修に割けるリソース

目的はともかく、2〜3個目は個人開発では明白なので考える必要はあまりない。業務で規模が大きいアプリを触る場合に検討が必要な事項といえる。

目的に関しては今回は「定期的なアップグレード、将来的なトラブル回避」あたりになるだろうか。

テストカバレッジを十分な状態にする

アップグレード前後できちんと動作するかのチェックのためにカバレッジを十分な状態にしておく必要がある。

私の場合はsimplecov gemを使用してカバレッジを確認するようにしている。

github.com

gem test groupeにsimplecoveを追加

test_helper.rbの先頭に定型文追加するだけでセットアップが完了する。

# frozen_string_literal: true

require 'simplecov'
SimpleCov.start

テストを走らせたあとに専用画面を開くとカバレッジを確認することができる。 これで動作検証に十分かどうかを事前に確認するようにした。

$ bin/rails test:all
$ open coverage/index.html

RubyRailsの対応バージョンを確認する

どちらかのメジャーバージョンがあると対応していないこともあるので事前チェックはしておいたほうがよい。

アップグレード

Rails以外のgemのアップグレード

bundle outdated で最新版とのバージョン差をチェックする。

Gem                  Current  Latest   Requested  Groups
actioncable          7.1.2    7.1.3
actionmailbox        7.1.2    7.1.3
actionmailer         7.1.2    7.1.3
actionpack           7.1.2    7.1.3
actiontext           7.1.2    7.1.3
actionview           7.1.2    7.1.3
activejob            7.1.2    7.1.3
activemodel          7.1.2    7.1.3
activerecord         7.1.2    7.1.3
activestorage        7.1.2    7.1.3
activesupport        7.1.2    7.1.3

<< 中略 >>

tailwindcss-rails    2.0.32   2.3.0    >= 0       default
turbo-rails          1.5.0    2.0.3    >= 0       default
zeitwerk             2.6.12   2.6.13

今回は2ヶ月ぶりぐらいになってしまったので結構バージョンに差分が生じていた。

つづいて、dev / testグループのgemに絞ってアップグレードする

bundle update -g development -g test

伊藤さんのアップグレード手順を参考にしているが、トラブルが発生した際の原因の切り分けが用意になるように段階を経てアップグレードしている印象だ。

テスト実行→通過。やったぜ。

つづいてトラブルが起こりそうなgemを1個ずつアップグレードしていく。

$ bundle outdated
<<中略>>

pagy               6.2.0    7.0.2    >= 0       default

<<中略>>

pagyがメジャーバージョンアップしていて不穏そうなのでこれだけアップグレードしてみる。

こちらもテスト通過。やったぜ。

不安なgemがなくなった段階でRails以外をアップデートする。Gemfile.lockRailsにバージョン固定をセットしておいて、$ bundle updateを実行する。

テストと手動の動作確認をしてみて問題なければOK。

Rubyのバージョンをアップグレードする

今回の主目的の一つ。 Rubyのバージョンが昨年末に3.3に上がっているのでその対応をしていく。

brewからrbenvのバージョンアップをして最新版のRubyを取得して、rbenvからRubyをアップグレードの手順で進める。

$ rbenv versions
$ brew upgrade rbenv
$ rbenv install --list

Rubyのアップグレードが完了したらGemfileに反映させる。

# Gemfile

ruby '3.3.0'

最新版のRubyに対応させるため、ここで$ bundle updateを再度実行する。 ここでもテスト。テストが通ったら一旦プルリクにする。

アップグレードをGitHub Actionsに反映させる

CICDを入れている場合はそちらで使用しているRubyのバージョンを反映させないと動作しなくなってしまう。

自分の場合はGitHub Actionsを使っていたので設定ファイルを修正しました。

Railsをアップグレードする

ついにRailsをアップグレードする段階までやってきました。

GemfileのRailsのバージョンを最新版(今回は7.1.3)に指定してbundle updateします。

# Gemfile

gem 'rails', '7.1.3'
$ bundle update rails

続いてアプリにRailsのバージョンアップを反映させます。

$ rails app:update
      force  config/environments/development.rb
   identical  config/environments/production.rb
   identical  config/environments/test.rb
       exist  config/initializers
   identical  config/initializers/assets.rb
   identical  config/initializers/content_security_policy.rb
      create  config/initializers/cors.rb
   identical  config/initializers/filter_parameter_logging.rb
   identical  config/initializers/inflections.rb
   identical  config/initializers/new_framework_defaults_7_1.rb
   identical  config/initializers/permissions_policy.rb
      remove  config/initializers/cors.rb
       exist  bin
   identical  bin/rails
   identical  bin/rake
   identical  bin/setup
       rails  active_storage:update

対話式にファイルをバージョンのデフォルト状態に修正するかを選択できます。dでdiff、差分を確認できるので確認してy or nで回答していきます。 私の場合は参考にしている伊藤さんが「rails app:updateコマンドのdiffでざっと確認してy、そのあと改めて確認して適宜修正」という流れで作業しているとのことで参考にしています。

https://railsdiff.org/ で旧バージョンと新バージョンの差分をチェック。 特にgemは新しく入るが、rails app:updateではインストールされないので追加する。

動作確認

アップグレード後に動作するかを確認します。

コンソール(rails c)→サーバー(rails s)→テスト の順番で動作するかどうかを見ていきます。

今回はRubyのバージョンアップ時にローカルにforemangemが欠落したようでサーバーが起動しない状態になりました。$ gem install foremanで解消しています。

手動チェック

機械的な確認だけでなく開発サーバーを立ち上げて手動と目視のチェックを行います。

私のサービスの場合は、ユーザー登録や地点登録ができるかどうかをチェックしました。

プルリク→デプロイ

ここまで完了して問題がなければ再度リモートリポジトリにプッシュして、本番環境にデプロイします。

すんなりいくわけもなく、GitHub Actionsのデプロイ側でエラーが出てしまいました。

デプロイでRubyバージョンエラー

ログを読んでみるとRuby3.2.2で動作している部分があり、Gemfileに記述したバージョンとミスマッチが生じていることが問題のようです。

今回はGitHub Actions上で動作するDockerの設定に修正が入ってなかったことが要因でした。

修正して再デプロイ、Fly.ioの仕様で数回デプロイにチャレンジする形になりましたが、最終的にデプロイできました🙌

終わりに

Fly.ioでデプロイが数回落ちるのは初めてでしたが、原因が読み取れないログだった上に「クラッシュした」と出力されていたのでメモリ不足と予想して繰り返しチャレンジしてみました。

個別で環境が異なるためエラーが出た場合の対応が大変ですが、アップグレード対応を溜め込むのもあとが面倒なのでぜひチャレンジしてください。 お手元でTryする際には、参考記事も見てチャレンジしてみてください。この記事を書くときも以前のアップグレードでも大変お世話になりました。

参考記事