Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Upgrade Rails 101: The Roadmap to Smooth Upgrad...

Upgrade Rails 101: The Roadmap to Smooth Upgrades (Southeast Ruby '19)

I presented this workshop on August 1st, 2019 at Southeast Ruby.

It details a series of exercises for crafting a Rails Upgrade roadmap.

The main goal of the workshop is to explain what our process looks like at fastruby.io and how you can apply to a sample Rails application.

Thanks to the conference organizers, sponsors, and attendees! :)

Ernesto Tagwerker

August 01, 2019
Tweet

More Decks by Ernesto Tagwerker

Other Decks in Programming

Transcript

  1. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 15 $ git clone \

    [email protected]:fastruby/e-petitions.git $ cd e-petitions $ git fetch origin docker:docker $ git checkout docker
  2. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 17 $ docker-compose exec app

    \ rspec spec/models/admin_user_spec.rb ... Finished in 22.24 seconds (files took 7.65 seconds to load) 81 examples, 0 failures
  3. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Exercise #1: Check Pre-Requisites Time:

    15 minutes https://fastruby.io/upgrade#1 https://fastruby.io/upgrade#2 https://fastruby.io/upgrade#3
  4. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 31 Exercise #2: Check Test

    Coverage Time: 15 minutes https://fastruby.io/upgrade#4
  5. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 48 $ docker-compose exec app

    bundle outdated Fetching gem metadata from https://rubygems.org/. Resolving dependencies..... Outdated gems included in the bundle: * actionmailer (newest 5.2.3, installed 4.2.11.1) * actionpack (newest 5.2.3, installed 4.2.11.1) * actionview (newest 5.2.3, installed 4.2.11.1) * activejob (newest 5.2.3, installed 4.2.11.1) * activemodel (newest 5.2.3, installed 4.2.11.1) * activerecord (newest 5.2.3, installed 4.2.11.1) * activesupport (newest 5.2.3, installed 4.2.11.1) ...
  6. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade $ docker-compose exec app \

    bundle_report outdated ... aws-sdk 2.11.314: released 19 days ago (latest version, 3.0.1, released almost 2 years ago) 0 gems are sourced from git 44 of the 139 gems are out-of-date (32%)
  7. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade For every fixed dependency declaration

    we change: 53 $ docker-compose down --volumes $ docker-compose up --build -d
  8. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade For every fixed dependency declaration

    we change: 54 $ docker-compose exec app \ rspec spec/lib/atomic_dalli_store_spec.rb
  9. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 57 Exercise #3: Pessimistic Dependencies

    Time: 10 minutes https://fastruby.io/upgrade#5 https://fastruby.io/upgrade#6
  10. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 64 $ docker-compose exec app

    next --init Created Gemfile.next (a symlink to your Gemfile). Your Gemfile has been modified to support dual-booting! There's just one more step: modify your Gemfile to use a newer version of Rails using the `next?` helper method. For example, here's how to go from 5.2.3 to 6.0: if next? gem "rails", "6.0.0" else gem "rails", "5.2.3" end
  11. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 65 # Gemfile def next?

    File.basename(__FILE__) == "Gemfile.next" end source ‘https://rubygems.org' gem 'rails', '4.2.11.1'
  12. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 66 # Gemfile if next?

    gem 'rails', '~> 5.0.7' else gem 'rails', '4.2.11.1' end
  13. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 68 # Dockerfile COPY Gemfile

    Gemfile.lock ./ COPY Gemfile.next Gemfile.next.lock ./ RUN gem install bundler -v=1.17.3 RUN bundle install RUN next bundle install COPY . .
  14. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 69 $ docker-compose down $

    docker-compose up --build -d $ docker-compose exec app \ ./bin/docker-setup
  15. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 71 $ docker-compose exec app

    \ bundle_report compatibility --rails-version=5.0.7 => Incompatible with Rails 5.0.7 (with new versions that are compatible): These gems will need to be upgraded before upgrading to Rails 5.0.7. rails-dom-testing 1.0.9 - upgrade to 2.0.3 test_after_commit 1.2.2 - new version, 1.2.2, is not compatible with Rails 5.0.7 2 gems incompatible with Rails 5.0.7
  16. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 78 $ docker-compose exec app

    \ next rspec spec/models rake aborted! Bundler::GemRequireError: There was an error while trying to load the gem 'test_after_commit'. Gem Load Error is: after_commit testing is baked into rails 5, you no longer need test_after_commit gem Backtrace for gem load error is: /Users/etagwerker/.rvm/gems/ruby-2.4.5@petitions/gems/ test_after_commit-1.1.0/lib/test_after_commit.rb:4:in `<top (required)>' /Users/etagwerker/.rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/ bundler/runtime.rb:81:in `require' /Users/etagwerker/.rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/ bundler/runtime.rb:81:in `block (2 levels) in require' /Users/etagwerker/.rvm/rubies/ruby-2.4.5/lib/ruby/site_ruby/2.4.0/ bundler/runtime.rb:76:in `each'
  17. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 81 $ docker-compose exec app

    \ next rspec spec/models NoMethodError: undefined method `hide_action' for Delayed::Web::ApplicationController:Class # ./config/initializers/delayed_web.rb:10:in `block in <top (required)>' # ./config/initializers/delayed_web.rb:7:in `class_eval' # ./config/initializers/delayed_web.rb:7:in `<top (required)>' # /Users/etagwerker/.rvm/gems/ruby-2.4.5@petitions/gems/ activesupport-5.0.7.2/lib/active_support/dependencies.rb:287:in `load' # /Users/etagwerker/.rvm/gems/ruby-2.4.5@petitions/gems/ activesupport-5.0.7.2/lib/active_support/dependencies.rb:287:in `block in load' # /Users/etagwerker/.rvm/gems/ruby-2.4.5@petitions/gems/ activesupport-5.0.7.2/lib/active_support/dependencies.rb:259:in `load_dependency'
  18. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 82 # config/initializers/delayed_web.rb Delayed::Web::ApplicationController.class_eval do

    include Authentication, FlashI18n hide_action :admin_request? def admin_request? true end protected def admin_login_url main_app.admin_login_url end end
  19. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 83 # config/initializers/delayed_web.rb Delayed::Web::ApplicationController.class_eval do

    include Authentication, FlashI18n protected def admin_request? true end def admin_login_url main_app.admin_login_url end end
  20. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 86 $ docker-compose exec app

    \ next rspec spec/models DEPRECATION WARNING: ActiveRecord::Base.raise_in_transactional_callbacks= is deprecated, has no effect and will be removed without replacement. (called from <top (required)> at /usr/src/app/ config/environment.rb:5) DEPRECATION WARNING: #table_exists? currently checks both tables and views. This behavior is deprecated and will be changed with Rails 5.1 to only check tables. Use #data_source_exists? instead. (called from table_exists? at / usr/src/app/app/models/site.rb:23) DEPRECATION WARNING: Passing an argument to force an association to reload is now deprecated and will be removed in Rails 5.1. Please call `reload_rejection` instead. (called from rejection at /usr/src/app/app/models/petition.rb:639) ...
  21. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 88 Exercise #5: next rspec

    spec/models Time: 20 minutes https://fastruby.io/upgrade#8
  22. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 91 $ docker-compose exec app

    \ next rspec spec/lib DEPRECATION WARNING: `config.serve_static_files` is deprecated and will be removed in Rails 5.1. Please use `config.public_file_server.enabled = true` instead. (called from block in <top (required)> at /usr/src/app/config/environments/ test.rb:16) DEPRECATION WARNING: `config.static_cache_control` is deprecated and will be removed in Rails 5.1. Please use `config.public_file_server.headers = { 'Cache-Control' => 'public, max- age=3600' }` instead. (called from block in <top (required)> at /usr/src/app/config/environments/ test.rb:17)
  23. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 92 Exercise #6: next rspec

    spec/lib Time: 10 minutes https://fastruby.io/upgrade#9
  24. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 95 $ docker-compose exec app

    \ next rspec spec/controllers DEPRECATION WARNING: Using positional arguments in functional tests has been deprecated, in favor of keyword arguments, and will be removed in Rails 5.1. Deprecated style: get :show, { id: 1 }, nil, { notice: "This is a flash message" } New keyword style: get :show, params: { id: 1 }, flash: { notice: "This is a flash message" }, session: nil # Can safely be omitted. (called from block (4 levels) in <top (required)> at /usr/src/app/spec/ controllers/admin/petition_tags_controller_spec.rb:46) DEPRECATION WARNING: Using positional arguments in functional tests has been deprecated, in favor of keyword arguments, and will be removed in Rails 5.1.
  25. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade # Gemfile group :development, :test

    do gem 'next_rails', '~> 1.0.1' # … gem 'rubocop' gem 'rubocop-rails' end
  26. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 97 $ docker-compose down $

    docker-compose up --build -d $ docker-compose exec app \ ./bin/docker-setup
  27. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 98 $ docker-compose exec app

    \ rubocop \ --only Rails/HttpPositionalArguments \ --require rubocop-rails --auto-correct spec/controllers
  28. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 100 Exercise #7: next rspec

    spec/controllers Time: 15 minutes https://fastruby.io/upgrade#10
  29. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Unofficial Guides 103 1.https://fastruby.io/blog/rails/upgrades/upgrade-to-rails-3.html 2.https://fastruby.io/blog/rails/upgrades/upgrade-to-rails-3-1.html

    3.https://fastruby.io/blog/rails/upgrades/upgrade-to-rails-3-2.html 4.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-3-2-to-4-0.html 5.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-4-0-to-4-1.html 6.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-4-1-to-4-2.html 7.https://fastruby.io/blog/rails/upgrades/active-record-5-1-api-changes.html 8.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-4-2-to-5-0.html 9.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-5-0-to-5-1.html 10.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-5-1-to-5-2.html 11.https://fastruby.io/blog/rails/upgrades/upgrade-rails-from-5-2-to-6-0.html
  30. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade ... ✅ 2.3 3.0 ✅

    3.0 3.1 ✅ 3.1 3.2 ✅ 3.2 4.0 ✅ 4.0 4.1 ✅ 4.1 4.2 ✅ 4.2 5.0 ✅ 5.0 5.1 ✅ 5.1 5.2 ✅ 5.2 6.0 108 Gemfile Gemfile.next { }
  31. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade # config/environments/test.rb Rails.application.configure do #

    ... # Raise on deprecation notices config.active_support.deprecation = :raise # ... end 119
  32. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade # Rakefile # ... task

    default: %i[ bundle:audit brakeman:check spec spec:javascripts cucumber ] 121
  33. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade namespace :bundle do desc "Audit

    bundle for any known vulnerabilities" task :audit do unless system "bundle-audit check --update" exit 1 end end end 122
  34. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 124 # Gemfile source 'https://rubygems.org'

    git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") "https://github.com/#{repo_name}.git" end if next? gem 'rails', github: 'rails/rails' else gem 'rails', '~> 6.0.0.rc2' end
  35. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Resources 127 1.https://github.com/clio/ten_years_rails 2.https://github.com/alphagov/e-petitions 3.https://github.com/rubyperu/ready4rails

    4.https://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#the-upgrade-process 5.https://fastruby.io/blog/tags/upgrades 6.https://semver.org 7.https://github.com/Shopify/bootboot 8.https://github.com/fastruby/rails_upgrader 9.http://railsdiff.org 10.https://github.com/hintmedia/moderate_parameters 11.https://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#the-update-task