Slide 1

Slide 1 text

Upgrade Rails 101 Philly.rb, April 2019

Slide 2

Slide 2 text

Who is this talk for? 2

Slide 3

Slide 3 text

Outline: Step #1; Exercise #1; Step #2; Exercise #2; and so on… 3

Slide 4

Slide 4 text

Goal: The Upgrade Roadmap 4

Slide 5

Slide 5 text

Ernesto Tagwerker (he/him) @etagwerker

Slide 6

Slide 6 text

Founder & Software Engineer at Ombu Labs

Slide 7

Slide 7 text

Founder & Software Engineer at FastRuby.io

Slide 8

Slide 8 text

Is upgrading a good idea?

Slide 9

Slide 9 text

Does your build pass? 9

Slide 10

Slide 10 text

Does your app have decent test coverage? 10

Slide 11

Slide 11 text

Exercise #1: Calculate Test Coverage

Slide 12

Slide 12 text

$ git clone [email protected]:fastruby/e-petitions.git If you don’t have an outdated Rails app

Slide 13

Slide 13 text

SimpleCov 13

Slide 14

Slide 14 text

14 # Gemfile group :test do gem 'simplecov', require: false end

Slide 15

Slide 15 text

15 # spec/spec_helper.rb if ENV['COVERAGE'] == 'true' require 'simplecov' SimpleCov.start 'rails' end

Slide 16

Slide 16 text

16 # Bash $ COVERAGE=true bundle exec rake

Slide 17

Slide 17 text

Exercise #1 Time:10 minutes 17

Slide 18

Slide 18 text

Is upgrading a good idea?

Slide 19

Slide 19 text

Upgrading is always* a good idea 19

Slide 20

Slide 20 text

Let’s assume your application is well covered 20

Slide 21

Slide 21 text

Pessimistic Dependencies Checkup

Slide 22

Slide 22 text

Dependencies should be pessimistic 22

Slide 23

Slide 23 text

23 # Gemfile (fixed version) source 'https://rubygems.org' gem 'rails', '4.2.7'

Slide 24

Slide 24 text

24 $ bundle update $ cat Gemfile.lock | grep rails rails (4.2.7)

Slide 25

Slide 25 text

25 # Gemfile (pessimistic versions) source 'https://rubygems.org' gem 'rails', '~> 4.2.7'

Slide 26

Slide 26 text

26 $ bundle update $ cat Gemfile.lock | grep rails rails (4.2.11.1)

Slide 27

Slide 27 text

Exercise #2: Relax your Gemfile

Slide 28

Slide 28 text

Analyze your Gemfile 28

Slide 29

Slide 29 text

Improve dependency declarations 29

Slide 30

Slide 30 text

30 $ bundle update

Slide 31

Slide 31 text

31 $ bundle exec rake

Slide 32

Slide 32 text

Does your build pass? 32

Slide 33

Slide 33 text

33 Exercise #2 Time:10 minutes

Slide 34

Slide 34 text

What happened? 34

Slide 35

Slide 35 text

Find Outdated Dependencies & Track Deprecation Warnings

Slide 36

Slide 36 text

“Couldn’t I just bump the version of Rails?” 36

Slide 37

Slide 37 text

How many outdated dependencies do you have? 37

Slide 38

Slide 38 text

Exercise #3: How outdated is your app?

Slide 39

Slide 39 text

39 $ 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) ...

Slide 40

Slide 40 text

40 # Gemfile group :development do gem 'ten_years_rails' end

Slide 41

Slide 41 text

41 $ bundle

Slide 42

Slide 42 text

42 $ bundle_report outdated redcarpet 3.0.0: released over 5 years ago (latest version, 3.4.0, released over 2 years ago) bootstrap-sass 3.3.7: released over 2 years ago (latest version 3.4.1, released about 2 months ago) ... mail 2.7.0: released over 1 year ago (latest version, 2.7.1, released 6 months ago) activesupport 5.1.6: released about 1 year ago (latest version, 5.2.3, released 11 days ago) railties 5.1.6: released about 1 year ago (latest version, 5.2. released 11 days ago) 0 gems are sourced from git 65 of the 102 gems are out-of-date (64%)

Slide 43

Slide 43 text

43 $ bundle_report compatibility --rails-version=5.2.0 0 gems incompatible with Rails 5.2.0 (this is for an app running Rails 5.1.4)

Slide 44

Slide 44 text

44 $ bundle_report compatibility --rails-version=6.0.0.beta3 => Incompatible with Rails 6.0.0.beta3 (with new versions that are compatible): These gems will need to be upgraded before upgrading to Rails 6.0.0.beta3. 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.beta3 (this is for an app running Rails 5.1.4)

Slide 45

Slide 45 text

45 # spec/rails_helper.rb require 'deprecation_tracker' RSpec.configure do |config| if ENV["DEPRECATION_TRACKER"] DeprecationTracker.track_rspec( config, shitlist_path: "spec/support/deprecation_warning.shitlist.json", mode: ENV["DEPRECATION_TRACKER"], transform_message: -> (message) { message.gsub("#{Rails.root}/", "") } ) end # ...

Slide 46

Slide 46 text

46 $ DEPRECATION_TRACKER=save bundle exec rake

Slide 47

Slide 47 text

47 Exercise #3 Time:15 minutes

Slide 48

Slide 48 text

What happened? 48

Slide 49

Slide 49 text

Trust The Process

Slide 50

Slide 50 text

Gradual version jumps 50

Slide 51

Slide 51 text

... ✅ 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 51 Gemfile Gemfile.next { }

Slide 52

Slide 52 text

Every deprecation warning is a story 52

Slide 53

Slide 53 text

Every failing scenario is a story 53

Slide 54

Slide 54 text

Ship backwards- compatible changes first 54

Slide 55

Slide 55 text

Dual Boot & Start Upgrading

Slide 56

Slide 56 text

Enough talk, let’s bump that Rails version 56

Slide 57

Slide 57 text

57 $ 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

Slide 58

Slide 58 text

58 # Gemfile def next? File.basename(__FILE__) == "Gemfile.next" end source 'https://rubygems.org' gem 'rails', '~> 5.1.1’

Slide 59

Slide 59 text

59 # Gemfile if next? gem 'rails', '~> 5.2.3' else gem 'rails', '~> 5.1.4' end

Slide 60

Slide 60 text

60 $ BUNDLE_GEMFILE=Gemfile.next bundle install

Slide 61

Slide 61 text

Incompatibilities 61

Slide 62

Slide 62 text

62 $ 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 ...

Slide 63

Slide 63 text

Failures 63

Slide 64

Slide 64 text

64 $ 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 `' /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'

Slide 65

Slide 65 text

65 # Gemfile # ... group :test do gem 'nokogiri' gem 'shoulda-matchers' gem 'pickle' gem 'test_after_commit' unless next? end

Slide 66

Slide 66 text

66 $ 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 ' # ./config/initializers/delayed_web.rb:7:in `class_eval' # ./config/initializers/delayed_web.rb:7:in `' # /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'

Slide 67

Slide 67 text

67 # 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

Slide 68

Slide 68 text

68 # 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

Slide 69

Slide 69 text

Deprecation Warnings 69

Slide 70

Slide 70 text

70 $ 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 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 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 at /Users/etagwerker/Projects/ ombulabs/fastruby.io/spec/controllers/ contacts_controller_spec.rb:52) ..........

Slide 71

Slide 71 text

Find References To Deprecated API

Slide 72

Slide 72 text

https://edgeguides.rubyonrails.org/ upgrading_ruby_on_rails.html Official Guides

Slide 73

Slide 73 text

Unofficial Guides 73 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

Slide 74

Slide 74 text

74 Exercise #4 Time: 20 minutes

Slide 75

Slide 75 text

What happened? 75

Slide 76

Slide 76 text

How To Stay Current

Slide 77

Slide 77 text

Add `bundler-audit` to your tests 77

Slide 78

Slide 78 text

Treat new deprecation warnings as exceptions 78

Slide 79

Slide 79 text

79 # 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.beta3' end

Slide 80

Slide 80 text

Thank you! @etagwerker 80

Slide 81

Slide 81 text

Resources 81 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.