はじめに
Heroku-16 Stackで動いているアプリケーションがあり、こちらが2021/6にEOLを迎える。
それに伴いHeroku Stackを上げるとRubyのバージョンも上げないといけなかった。
せっかくだったらこの機会に最新にしようと思い、バージョンを上げたのでその時の注意事項をメモ書き程度に残しておく。
Gemfile
まず元々のGemfile
# 一部抜粋
gem 'rails', github: 'rails/rails', branch: "5-0-stable"
gem 'mysql2', '>= 0.3.18', '< 0.5'
gem 'puma', '~> 3.0'
gem 'rspec-rails', '~> 3.5'
gem 'factory_girl_rails'
Rubyのバージョン指定はしておらず、Herokuのデフォルトのバージョンになっていた。
今回はRubyとRailsのバージョンを上げたいので以下を設定してみた。
ruby "3.0.0"
gem 'rails', '~> 6.1', '>= 6.1.3'
これで環境を作り直そうとした結果以下のエラー
Bundler could not find compatible versions for gem "bundler":
In Gemfile:
bundler-audit was resolved to 0.6.0, which depends on
bundler (~> 1.2)
license_finder was resolved to 3.0.2, which depends on
bundler
rails (~> 6.1, >= 6.1.3) was resolved to 6.1.3, which depends on
bundler (>= 1.15.0)
Current Bundler version:
bundler (2.2.3)
This Gemfile requires a different version of Bundler.
Perhaps you need to update Bundler by running `gem install bundler`?
Could not find gem 'bundler (~> 1.2)', which is required by gem 'bundler-audit',
in any of the sources.
bundler関連の問題でうまく環境が作れないようだった。
どうやらbundlerが1.15.3で作ろうとしているのが問題のようだった。
Gemfile.lockを消した状態でbundlerのバージョンを上げてbundle installした。
bundlerは2.2.11になった。
# 一部抜粋
+ RUBY VERSION
+ ruby 3.0.0p0
BUNDLED WITH
- 1.15.3
+ 2.2.11
rexml
gem installすると以下のエラー
LoadError - cannot load such file -- rexml/document
こちらの記事を参考にしました。
gem 'rexml'
factory_girl
DEPRECATION WARNING: The factory_girl gem is deprecated. Please upgrade to factory_bot. See https://github.com/thoughtbot/factory_bot/blob/v4.9.0/UPGRADE_FROM_FACTORY_GIRL.md for further instructions. (called from <top (required)> at /usr/src/app/config/application.rb:17)
porter-web-dev | /usr/local/bundle/gems/activesupport-6.1.3/lib/active_support/dependencies.rb:332:in `require': cannot load such file -- rexml/document (LoadError)
factory_girlは非推奨なのでfactory_botにバージョンアップする。
- gem 'factory_girl_rails'
+ gem 'factory_bot'
rspecファイル内にてFactoryGirlをFactoryBotに置換。
更新が用意してくれている置換コマンドで割といい感じに置換できた。
mysql2
手元の環境はDockerで作成しているがmysql-client
がないと言われたのでdefault-mysql-client
に変更
Package mysql-client is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
- RUN apt-get install -y mysql-client
+ RUN apt-get install -y default-mysql-client
環境を立ち上げてみたがDBアクセスで以下エラー
Puma caught this error: Error loading the 'mysql2' Active Record adapter. Missing a gem it depends on? can't activate mysql2 (~> 0.5), already activated mysql2-0.4.10. Make sure all dependencies are added to Gemfile. (LoadError)
mysql2のバージョンも上げる。
- gem 'mysql2', '>= 0.3.18', '< 0.5'
+ gem 'mysql2', '~> 0.5.3'
puma
ローカル環境が立ち上がらない。
こちらの記事を参考にしました。
- ActiveSupport.halt_callback_chains_on_return_false = false
+ #ActiveSupport.halt_callback_chains_on_return_false = false
ローカル環境を立ち上げると証明書関連のエラー
こちらの記事を参考にpumaのバージョンも上げる。
- gem 'puma', '~> 3.0'
+ gem 'puma', '~> 5.2', '>= 5.2.1'
Rspec
ローカル環境も立ち上がりある程度動くようになったのでテストを通してみたところ全部失敗した。
Failure/Error:
raise WrongScopeError,
"`#{name}` is not available from within an example (e.g. an " \
"`it` block) or from constructs that run in the scope of an " \
"example (e.g. `before`, `let`, etc). It is only available " \
"on an example group (e.g. a `describe` or `context` block)."
`name` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).
こちらの記事を参考にしました。
- FactoryGirl.define do
+ FactoryBot.define do
factory :hoge do
- name 'テスト'
+ name {'テスト'}
end
end
config.before(:all) do
FactoryBot.reload
end
最終的に
以下のようなGemfileになった。
# 一部抜粋
ruby "3.0.0"
gem 'rails', '~> 6.1', '>= 6.1.3'
gem 'mysql2', '~> 0.5.3'
gem 'puma', '~> 5.2', '>= 5.2.1'
gem 'rexml'
gem 'rspec-rails', '~> 4.0', '>= 4.0.2'
gem 'factory_bot'
各バージョンの後方互換を調べる
ローカル環境が起動しひと通りアプリケーションが動くことを確認。
RSpecが全て通ることを確認。
この時点で8割方バージョンアップ完了だったが、念の為各バージョンで後方互換切られているところを中心に調べていくことにした。
Ruby2.3から3.0という記事はなかったので1バージョンずつ調べていった。
ruby2.4
特に問題なさそう。
ruby2.5
後方互換の話は特になし。
ruby2.6
範囲オブジェクトに影響あり。
git grep -i range
git grep "\.\."
あたりで範囲オブジェクトを使っている箇所を調べていった。
ruby2.7
こちらも範囲オブジェクト関連。
ruby3.0.0
1つずつ見てgrepしてみたが影響のありそうなものはそもそも使っていなかったので問題ないと判断した。
rails6.1.3
https://qiita.com/ryohashimoto/items/622c3bcfb3336cb9317e
https://railsguides.jp/upgrading_ruby_on_rails.html
cookiesの話が気になるがrails4との比較をしているのでrails5からのアップデートでは問題なしと判断した。
Heroku
以上の調査と修正によりバージョンアップ問題なしと判断し本番をHeroku-20 Stackに上げてデプロイ。
しかし本番でエラーが発生した。
ActiveRecord::ConnectionNotEstablished: SSL connection error: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
こちらの記事と同様の事象のようだった。
なんとか解消したかったが原因不明のため、記事と同様にHeroku-18 Stackにしたら問題なく動いた。
まとめ
今回所要時間15時間程度でバージョンアップすることができた。
ここまで早くできたのは以下の要因によるものと思われる。
- 元のバージョンがそこまで低くなかった。
- テストが書いてあった。
- 該当アプリケーションがシンプルな作りで機能がそこまで多くなく、検証すべき項目が少なかった。
せっかくバージョンを上げたので新バージョンで使えるようになった機能とかを使っていきたい。
まだ全然調べられていないがRails6からは標準でバルクインサートできるようになったらしい。
activerecord-import
とかgemを後入れしなくても良くなったのは嬉しい。
時間ができたら触ってみることにする。