無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

趣味で作っているサービスを Rails 5.0 から Rails 5.1 へアップグレードする

f:id:muziyoshiz:20170724152414p:plain

最近、趣味で作っているサービス(Admiral Stats)を Rails 5.0.0.1 から 5.1.2 にアップグレードしました。サービスが小さいので、それほど苦戦するポイントは無かったのですが、調べたこと、やったことをメモしておきます。

調べたこと

とりあえず、関連しそうな情報に一通り目を通しました。

アップグレード方針

上記のページを見る限り、今回は移行対象のアプリが小さいこともあり、特に問題もなくアップグレードできそうでした。

まず、「application.secretsですべてのキーをシンボルとして読み込むようになった」はコード中の参照箇所を確認して、問題なし。JWT のエンコード、デコード時に Rails.application.secrets.secret_key_base と参照していましたが、これは Rails 5.1 でも動作しました。

秘密情報の暗号化は、元々 MySQL のパスワードなどは Apache から環境変数(SetEnv)で渡していたので、この方針を踏襲することにして変更せず。config/environments/production.rb で config.read_encrypted_secrets = false と書いておいて、今まで通りに secrets.yml を使います。

Yarn のサポート、Webpack のサポート、デフォルトでのjQuery依存の廃止、については、引き続き jQuery を使うことにして今回は気にしないことに。

あと、主キーのデフォルト型が BIGINT に変更に変更される件については、テーブル作成時期によって主キーの型が変わるのは混乱しそうなので、INT に統一することにしました。アップグレード時に必要な作業は特にないですが、テーブル作成時に id: integer を付ければ OK(以下はその例)。ただ、これはうっかり忘れることが多そうなので、generate model 時に必ず自動で付くようにしたい……。

class CreateBlueprintStatuses < ActiveRecord::Migration[5.1]
  def change
    create_table :blueprint_statuses, id: :integer do |t|

やったこと

Rails 5.0 系の最新版へのアップグレード、および関連 gem のアップグレード

まずは Gemfileのバージョンを更新。

- gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
+ gem 'rails', '~> 5.0.0', '>= 5.0.4'

そして bundle update を実行。参考にしたページには bundle update rails を実行して rails 関係だけをアップグレードし、関連 gem は後回しにすべき、というアドバイスがあったのですが、すっかり忘れてました……。今回はそのまま続行。

最後に、動作確認のためにテストがある部分は rails test で確認し、ない部分は手作業で軽くポチポチ確認。

Rails 関係では特に問題ありませんでしたが、rack-cors が 0.4.1 から 1.0.0 に上がった影響で動作が少し変わっていて rails test が失敗。その部分のテストコードを修正しました。

あとは、Capistrano が 3.6.1 から 3.8.2 に変わった影響で、動かない部分と、Deprecation Notice が出る部分があったのでそこを修正。

  • Capfile の修正
- lock '3.6.1'
+ lock '3.8.2'
  • Capfile で Git SCM plugin のロードを明示
# Include default deployment tasks
require "capistrano/deploy"

# Future versions of Capistrano will not load the Git SCM plugin by default.
+ require "capistrano/scm/git"
+ install_plugin Capistrano::SCM::Git

Rails 5.1.2 へのアップグレード

先ほどと同じく、まずは Gemfile のバージョンを更新。

- gem 'rails', '~> 5.0.0', '>= 5.0.4'
+ gem 'rails', '~> 5.1.0', '>= 5.1.2'

次は bundle update を実行。関連 gem はアップグレード済みなので、今回は rails 関連の gem のみがアップグレードされました。

そして rails app:update を実行。bin 以下と config 以下のファイルが、新規作成されたり上書きされたりします。git で差分を見て、既存の設定を上書きしている部分以外は、基本的に採用しました。

  • bin/setup
    • bin/yarn の読み込みがコメントアウトされた状態で追加された。参考のために残した
  # Install JavaScript dependencies if using Yarn
  # system('bin/yarn')
  • bin/yarn (新規作成)
    • 今回は使わないが、呼び出し自体は上記の通りコメントアウトされているので残した
#!/usr/bin/env ruby
VENDOR_PATH = File.expand_path('..', __dir__)
Dir.chdir(VENDOR_PATH) do
  begin
    exec "yarnpkg #{ARGV.join(" ")}"
  rescue Errno::ENOENT
    $stderr.puts "Yarn executable was not detected in the system."
    $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
    exit 1
  end
end
  • config/application.rb
    • 以下の行が追加された。確認のうえで残した
+    config.load_defaults 5.1
  • config/cable.yml
    • Redis PubSub で使う prefix が追加された。設定しても、この自作サービス(Admiral Stats)では使わないが、自動生成されたまま残した
+  channel_prefix: admiral_stats_production
  • config/puma.rb
    • ビルトインサーバの設定。コメントが変わっただけ
  • config/routes.rb
    • 単純に空にされるだけなので、上書きされたものをもとに戻した
  • config/secrets.yml
    • 環境変数から読み込む運用にしているので、そのままにした
  • config/environments/development.rb
    • Cache-Control の表記が分かりやすい表記に変わった(max-age の長さは同じ)ため、そのまま残した
-      'Cache-Control' => 'public, max-age=172800'
+      'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}"
  • config/environments/production.rb
    • config.read_encrypted_secrets = true という行が追加されるが、これを false に変更した
  • config/initializers/assets.rb
    • 以下の行が追加された。Yarn は使っていないが、そのままにした
Rails.application.config.assets.paths << Rails.root.join('node_modules')
  • config/initializers/cors.rb
    • 基本的な設定が作成されたが、このファイルは元々作成済みだったため、元に戻した
  • config/initializers/new_framework_defaults_5_1.rb
    • 以下の内容で作成された。そのままにした。
# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 5.1 upgrade.
#
# Once upgraded flip defaults one by one to migrate to the new default.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.

# Make `form_with` generate non-remote forms.
Rails.application.config.action_view.form_with_generates_remote_forms = false

# Unknown asset fallback will return the path passed in when the given
# asset is not present in the asset pipeline.
# Rails.application.config.assets.unknown_asset_fallback = false

最後に、動作確認のためにテストがある部分は rails test で確認し、ない部分は手作業で軽くポチポチ確認して、リリースしました。

まとめ

5.0 から 5.1 へのアップグレードは、それほど詰まるところはありませんでした。アップグレードが溜まってると辛くなるので、早いうちにやっておいてよかったです。

ただ、当たり前の話ですが、アップグレード前にはちゃんとテストを整備しておかないとダメですね。今回のアップグレード対象は趣味のサービスで、テストより機能追加を優先してしまっていたので、今回のアップグレードはおっかなびっくりでした。なにか僕の気付いていない問題が見つかったら、報告頂けたら緊急で対応します……。