Keeping Your Rails Upgrades on Track

Alex Leaver
FlexMR Dev Blog

--

In the past 10 months, FlexMR has upgraded through 5 versions of Rails from 4.2 to 6.1. Our core platform is almost 14 years old with over 600,000 lines of code and this work has been one of FlexMR’s longest-running projects. After a lengthy PrototypeJS removal project we were finally able to upgrade from 4.2.

Over the past year, I’ve read countless blog posts, GitHub issues, changelog entries and have compiled a list of useful tools and a basic strategy for tackling the seemingly insurmountable task of a big Rails upgrade. This isn’t a step-by-step guide and every project is different, but across each iteration of Rails there was a common approach we could apply.

Test Coverage

Your tests will fail, a lot, you’ll think you’ve fixed them and they’ll fail again. You’ll get them working, come back from lunch and they’ll break again. You do not want to be doing this manually.

We use SimpleCov to ensure we maintain a high level of test coverage and builds that bring our test coverage below 90% will fail.

Project Structure

A successful Rails upgrade is a lot like a successful Christmas dinner. You need to plan work, timing is everything and if you mess it up then your family will be disappointed in you and wish your sister organised it instead.

In upgrading through 5 versions of Rails we had 10 epics for grouping individual stories:

  • Rails 5.0 pre-upgrade
  • Rails 5.0 upgrade

  • Rails 6.1 pre-upgrade
  • Rails 6.1 upgrade

Anything that could be worked on in isolation ahead of the “big bang” release of a Rails upgrade could go into a “pre-upgrade” epic, if it had a direct dependency on a Rails bump then it would go in an “upgrade” epic.

This way any story in a “pre-upgrade” epic could be picked up by any developer in isolation. Whereas anything in an “upgrade” epic needed to go out together as a single, higher risk “big bang” release.

Deprecation Warnings

There are many warnings in life that can be safely ignored; the Ikea assembly instructions about getting a friend to help you, or the service engine light on my car.

But you should never ignore Rails deprecation warnings as they’ll help you identify code that will be broken under the next version of Rails. This excellent blog post on FastRuby.io outlines different strategies for enabling and tracking deprecation warnings.

You can then compile a list of deprecation warnings in your codebase. We did this by running our automated tests, extracting the warnings from the output using a combination of grep , sed , sort and uniq.

From this list, a story would be created for each deprecation warning and added to the “pre-upgrade” epic.

next_rails

The output from bundle update rails is rather noisy on any moderately sized project. The next_railsgem provides several useful tools to assist with upgrading Rails.

It provides thebundle_report compatibility --rails-version=x.x.x command, which will list dependencies in your Gemfile that need to be updated ahead of any Rails update. Most of the time this can be updated in isolation and added to the “pre-upgrade” epic.

Upgrading Rails

Any developer considering a Rails upgrade has probably already encountered the official Rails project upgrade guide. Sometimes I read it to my son to help him off to sleep, but it is full of useful information about how to approach a Rails upgrade and details the key changes between each Rails version.

It also links to the release notes for each version which is also worth a read, especially if a particular change has broken your application.

RailsDiff.org

The app:update rake task helps backfill new files introduced in a new version of Rails, but this can be very noisy for existing config files in a mature project.

https://railsdiff.org/ helps massively with this by showing config file diffs between Rails versions. Using this information you can easily update your existing config files manually.

Maintain a Maintenance Mindset

After the first 3 upgrades, I started to feel like Sisyphus forever doomed to push a boulder up a hill for eternity. This could have been avoided by keeping on top of updates.

When a new version of Rails is released begin preparations for the upgrade, don’t put it off because before you know it’ll you’ll be tasked with upgrading through multiple versions of Rails and backporting CVE fixes.

--

--