Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RailsConf 2019: Upgrade Rails 101 Workshop

RailsConf 2019: Upgrade Rails 101 Workshop

This is a presentation about upgrading Rails applications following a process that has worked very well at fastruby.io

After following the steps in this presentation you will have the roadmap to get to the next version of Rails.

You can find the companion page to this workshop over here: https://fastruby.io/upgrade

F77032adcbe77d2777bb0e0c30873159?s=128

Ernesto Tagwerker

May 02, 2019
Tweet

Transcript

  1. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Upgrade Rails 101 The Roadmap

    to Smooth Upgrades RailsConf 2019
  2. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Who is this workshop for?

    2
  3. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Workshop Outline 3

  4. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Goal: The Upgrade Roadmap 4

  5. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade fastruby.io/ upgrade 5

  6. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade #RailsUpgrades 6

  7. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Ernesto Tagwerker (he/him)

  8. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Thanks to my main sponsor!

  9. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Thanks to my main sponsor!

  10. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Founder & Software Engineer at

    Ombu Labs
  11. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Founder & Software Engineer at

    FastRuby.io
  12. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade - “Upgrading Rails is easy,

    right?” - “Right, right, easy…”
  13. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Questions are welcome

  14. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Pre-Requisites

  15. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade An outdated Rails application

  16. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 16 $ bundle install

  17. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 17 $ bundle exec rake

  18. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 18 $ bundle exec rspec

  19. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 19 $ bundle exec rake

    test
  20. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade If you don’t have an

    outdated Rails app…
  21. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 21 $ git clone \

    git@github.com:fastruby/e-petitions.git
  22. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 22 $ cd e-petitions $

    ./bin/setup
  23. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Questions?

  24. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Exercise #1: Check Pre-Requisites Time:

    10 minutes https://fastruby.io/upgrade#1 https://fastruby.io/upgrade#2 https://fastruby.io/upgrade#3
  25. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Is your app ready for

    an upgrade?
  26. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade bundle update rails ?

  27. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Does your test suite succeed?

    27
  28. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Does your app have decent

    test coverage? 28
  29. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Exercise #2: Calculate Test Coverage

  30. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade SimpleCov 30

  31. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 31 # Gemfile group :test

    do gem 'simplecov', require: false end
  32. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 32 # spec/spec_helper.rb if ENV['COVERAGE']

    == 'true' require 'simplecov' SimpleCov.start 'rails' end
  33. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 33 $ COVERAGE=true bundle exec

    rake
  34. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Questions?

  35. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 35 Exercise #2: Check Test

    Coverage Time: 15 minutes https://fastruby.io/upgrade#4
  36. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Is upgrading a good idea?

  37. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Upgrading is always a good

    idea 37
  38. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Let’s assume your application is

    well covered 38
  39. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Trust The Process

  40. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Gradual version jumps 40

  41. @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 41 Gemfile Gemfile.next { }
  42. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade For every version jump: bundle

    install bundle exec rake Smoke test 42
  43. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Ship backwards-compatible changes first 43

  44. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Every deprecation warning is a

    story 44
  45. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Every failing scenario is a

    story 45
  46. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Tiny Pull Requests over One

    Huge PR 46
  47. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Tiny Changesets over Huge Changesets

    47
  48. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 1. Tweak 2. Test 3.

    Merge And Iterate
  49. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade The Version Jump Pull Request

    is Last 49
  50. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Pessimistic Dependencies Checkup

  51. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade SemVer 51

  52. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade <MAJOR version>.<MINOR version>.<PATCH version> 52

  53. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade

  54. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Rails 5.2.3 MAJOR: 5 MINOR:

    2 PATCH: 3 54
  55. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Dependencies should be pessimistic* 55

  56. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 56 # Gemfile (fixed version)

    source 'https://rubygems.org' gem 'rails', '4.2.7'
  57. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 57 $ bundle update $

    cat Gemfile.lock | grep rails rails (4.2.7)
  58. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 58 # Gemfile (pessimistic versions)

    source 'https://rubygems.org' gem 'rails', '~> 4.2.7'
  59. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 59 $ bundle update $

    cat Gemfile.lock | grep rails rails (4.2.11.1)
  60. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Exercise #3: Relax your Gemfile

  61. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Analyze your Gemfile 61

  62. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 62 $ bundle outdated Fetching

    gem metadata from https://rubygems.org/. Resolving dependencies..... Outdated gems included in the bundle: * actioncable (newest 5.2.3, installed 5.1.6) * actionmailer (newest 5.2.3, installed 5.1.6) * actionpack (newest 5.2.3, installed 5.1.6) * actionview (newest 5.2.3, installed 5.1.6) ...
  63. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade For every fixed dependency declaration:

    - Turn it into a pessimistic declaration 63
  64. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade For every fixed dependency declaration:

    64 $ bundle update
  65. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade For every fixed dependency declaration:

    65 $ bundle exec rake
  66. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Does your build pass? -

    Submit a PR - Create a story 66 … and move on to the next fixed dependency
  67. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Remember: One at a time

    67
  68. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Questions?

  69. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 69 Exercise #3: Relax your

    Gemfile Time: 10 minutes https://fastruby.io/upgrade#5
  70. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade What happened? 70

  71. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Dual Boot: Bundle Install

  72. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Let’s bump that Rails version

    72
  73. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Dual boot: There are many

    gems for that 73
  74. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 74 # Gemfile group :development

    do gem "ten_years_rails", git: "https://github.com/fastruby/ten_years_rails_conf_2018.git", branch: "fixes/ruby-2-2-syntax-error" end
  75. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 75 $ bundle install

  76. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 76 $ bundle_report outdated cucumber-rails

    1.4.0: released over 5 years ago (latest version, 1.7.0, released 11 days ago) rack-test 0.6.3: released over 4 years ago (latest version, 1.1.0, released 9 months ago) cucumber-wire 0.0.1: released over 3 years ago (latest version, 1.0.0, released 7 months ago) cucumber-core 1.5.0: released almost 3 years ago (latest version, 4.0.0, released 7 months ago) cucumber 2.4.0: released almost 3 years ago (latest version, 3.1.2, released 10 months ago) arel 6.0.4: released over 2 years ago (latest version, 9.0.0, released over 1 year ago) ... ... ... 35 of the 143 gems are out-of-date (24%)
  77. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 77 $ bundle_report compatibility --rails-version=6.0.0.rc1

    => Incompatible with Rails 6.0.0.rc1 (with new versions that ar compatible): These gems will need to be upgraded before upgrading to Rails 6.0.0.rc1. rails-controller-testing 1.0.2 - upgrade to 1.0.4 responders 2.4.0 - upgrade to 2.4.1 2 gems incompatible with Rails 6.0.0.rc1 (this is for an app running Rails 5.1.4)
  78. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 78 $ 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
  79. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 79 # Gemfile def next?

    File.basename(__FILE__) == "Gemfile.next" end source 'https://rubygems.org' gem 'rails', '~> 5.1.4’
  80. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 80 # Gemfile if next?

    gem 'rails', '~> 5.2.3' else gem 'rails', '~> 5.1.4' end
  81. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 81 $ next bundle install

  82. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 82 $ BUNDLE_GEMFILE=Gemfile.next \ bundle

    install
  83. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Incompatibilities 83

  84. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 84 $ BUNDLE_GEMFILE=Gemfile.next \ bundle

    install Bundler could not find compatible versions for gem "activesupport": In snapshot (Gemfile.lock): activesupport (= 4.2.1) In Gemfile: activeadmin was resolved to 1.0.0.pre4, which depends on arbre (>= 1.0.2, ~> 1.0) was resolved to 1.1.1, which depends on activesupport (>= 3.0.0) activeadmin was resolved to 1.0.0.pre4, which depends on inherited_resources (~> 1.6) was resolved to 1.7.0, which depends on .
  85. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Try to fix incompatibilities 85

  86. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade #DownTheRabbitHole

  87. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade You might have to remove

    dependencies, create user stories, and move on 87
  88. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 88 Exercise #4: next bundle

    install Time: 15 minutes https://fastruby.io/upgrade#6
  89. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Dual Boot: Test Suite

  90. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Assuming you can now next

    bundle install successfully... 90
  91. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 91 # On Rails >

    4.2 $ next bundle exec rake app:update
  92. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 92 # On Rails <=

    4.2 $ next bundle exec rake rails:update
  93. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 93 $ next bundle exec

    rake
  94. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Failures 94

  95. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 95 $ BUNDLE_GEMFILE=Gemfile.next \ bundle

    exec rake 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'
  96. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 96 # Gemfile group :test

    do gem 'nokogiri' gem 'shoulda-matchers' gem ‘pickle' unless next? gem ‘test_after_commit' end end
  97. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 97 $ BUNDLE_GEMFILE=Gemfile.next \ bundle

    exec rake 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'
  98. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 98 # 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
  99. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 99 # 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
  100. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Deprecation Warnings 100

  101. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 101 $ BUNDLE_GEMFILE=Gemfile.next bundle exec

    rake DEPRECATION WARNING: The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers. (called from block (3 levels) in <top (required)> at /Users/etagwerker/Projects/ ombulabs/fastruby.io/spec/controllers/ contacts_controller_spec.rb:20) .DEPRECATION WARNING: The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers. (called from block (4 levels) in <top (required)> at /Users/etagwerker/Projects/ ombulabs/fastruby.io/spec/controllers/ contacts_controller_spec.rb:32) ..DEPRECATION WARNING: The success? predicate is deprecated and will be removed in Rails 6.0. Please use successful? as provided by Rack::Response::Helpers. (called from block (4 levels) in <top (required)> at /Users/etagwerker/Projects/ ombulabs/fastruby.io/spec/controllers/ contacts_controller_spec.rb:52) ..........
  102. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Find References To Deprecated API

  103. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade https://edgeguides.rubyonrails.org/ upgrading_ruby_on_rails.html Official Guides

  104. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Unofficial Guides 104 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
  105. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade http://railsdiff.org/ RailsDiff

  106. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Find In Project 106

  107. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 107 Exercise #5: next bundle

    exec rake Time: 15 minutes https://fastruby.io/upgrade#7
  108. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade What happened? 108

  109. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade How To Stay Current How

    To Stay Current
  110. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Treat new deprecation warnings as

    exceptions 110
  111. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade # config/environments/test.rb Rails.application.configure do #

    ... # Raise on deprecation notices config.active_support.deprecation = :raise # ... end 111
  112. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Add bundler-audit to your default

    rake task 112
  113. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade # Rakefile # ... task

    default: %i[ bundle:audit brakeman:check spec spec:javascripts cucumber ] 113
  114. @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 114
  115. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Keep up with the upcoming

    releases 115
  116. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 116 # 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.rc1' end
  117. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 117 Exercise #6: Set Up

    to Stay Current Time: 5 minutes https://fastruby.io/upgrade#8
  118. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade @etagwerker #RailsUpgrades fastruby.io Feedback is

    welcome
  119. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade 119 Thank You!

  120. @etagwerker | #RailsUpgrades | https://fastruby.io/upgrade Resources 120 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