Can You Upgrade Rails in Increments?

Can You Upgrade Rails in Increments?

Ruby on Rails is a powerful web application framework that has evolved over the years, with new versions bringing in features, improvements, and security updates. As your application matures, keeping it up-to-date with the latest Rails version becomes crucial. However, the prospect of upgrading an entire Rails application can be daunting. In this blog post, we’ll explore whether it’s possible to upgrade your Rails application in increments and how to go about it.

First, you may be wondering - what does it mean to upgrade in increments?

There are two ways you can interpret “increments”. I will cover both interpretations below.

Say you want to upgrade from Rails 5 to Rails 7. Instead of jumping directly to Rails 7, you might first upgrade to Rails 5.1, then to Rails 5.2, and so on, until you reach the desired version. The Rails Upgrade Guide opens a new window always recommends this approach of upgrading Rails one minor version at a time, which is the recommendation we follow here at FastRuby.io. There are simply too many changes between minor versions, let alone between major versions, to make skipping versions a good idea.

Now that we got that caveat out of the way, let’s talk about what this article is really about: can you upgrade between minor versions in increments? The short answer is yes. While we have done focused upgrades for many of our past clients, by that I mean working with a client for a short amount of time to focus solely on the upgrade, it’s not the only way to do an upgrade. In our fixed-cost monthly maintenance service opens a new window , we work with clients to progressively pay down tech debt, including upgrading Rails versions in increments.

While the process is the same no matter the timeline, here are a few reasons why you might want to upgrade in increments:

  • Not as disruptive to feature development workflow
  • Allows you to identify and address issues incrementally, reducing the overall risk associated with a major upgrade.
  • If your application has a significant amount of custom code or if it diverges significantly from typical Rails conventions, a gradual upgrade may be more practical as it allows you to address specific issues in your custom code incrementally.

Now that you know the benefits of upgrading in increments, you might be wondering how to best approach the process. Here’s the way I would approach the incremental upgrade process:

  1. Plan your upgrade
  2. Get prepared technically before attempting the upgrade process
  3. Upgrade Ruby, if desired
  4. Work through the upgrade process in steps

Plan your upgrade

Create a plan for your upgrade before you start. Do you want to upgrade just one minor version? Or do you plan to do multiple major Rails jumps? Would you want to upgrade Ruby as well? The Rails Upgrade guide opens a new window also suggests, as we do, to upgrade Ruby first, if needed, before you upgrade Rails. Here’s our compatibility table opens a new window to check if you also need to do a Ruby upgrade.

Get prepared technically

There are several things you can do to get prepared. The most important step you can take to get prepared is to have a robust test suite. What do I mean by a “robust test suite”? In our experience, we have found that the most successful upgrade projects have at least 70% test coverage with few flaky tests opens a new window .

But don’t fret if that doesn’t apply to you - you might just have to do more manual QA to ensure things are working smoothly. Our article 10 strategies for upgrading Rails applications with low test coverage opens a new window has some strategies to use if you’re facing an upgrade with low test coverage.

Two steps that are not as important, but will make the upgrade process easier, are to upgrade dependencies and to track deprecation warnings. These two items are not essential because you will tackle each of these things during the upgrade process.

Tracking deprecation warnings

There are two main ways to get deprecation warnings applicable to your codebase. The first way is to ensure that you are setting your deprecation notices to print out when you run your tests. Then you can run your test suite and gauge how many deprecation warnings you have that way. This might not work so well if you don’t have a robust test suite.

The second way to get deprecation warnings is to set up a deprecation warning tracker in production, which you can learn how to do in our article The Complete Guide for Deprecation Warnings in Rails opens a new window .

Upgrade dependencies

My article How to Delay a Rails Upgrade opens a new window gives you some tips on how to how to evaluate the current state of your Rails dependencies. When you’re upgrading dependencies, make sure that your updated dependencies work in both your current and your target version of Rails.

Upgrade Ruby, if needed

As mentioned above in the ‘Plan your upgrade’ section, a Ruby upgrade might be necessary depending on whether you are already using the Ruby version required for your target Rails version. If a new Ruby version is needed, we’ve got you covered. Read through the below section to learn how to approach the upgrade - here at FastRuby.io we approach the Ruby upgrade the same way as the Rails one. We also have a separate guide to help you upgrade Ruby opens a new window .

Work through the upgrade in steps

We have written about this process many times (we even have a book opens a new window !) Our upgrade process is roughly the same for every upgrade we do, no matter whether it’s done all at once or in increments:

  1. Fix deprecation warnings for the current version

If you followed my instructions earlier, you should have a list of these deprecations either from CI or through your deprecation warning tracker. Fix these first and incorporate them into your main branch.

If you are upgrading incrementally, you probably aren’t going to be able to fix your deprecations all at once. One thing you can do is to commit to fixing a certain number of deprecations over an amount of time (per sprint, per month, etc.) That number is going to depend on your specific project - the number of deprecations that exist and the complexity of each deprecation’s fix. When we do incremental upgrades here at FastRuby.io, we tend to prioritize - for instance, fixing the deprecations that appear the most in our client’s deprecation warning trackers and/or CI.

Once you finish fixing all instances of a deprecation warning, I would add safeguards to avoid re-introducing that deprecation regression. We have an article to help you add those safeguards to avoid deprecation regressions opens a new window .

  1. Dual boot current and next versions of Rails

If you’ve read any of FastRuby.io’s articles before, you know that we favor the dual boot technique opens a new window to run both the current and the target Rails version locally/ and in CI. Using conditionals, you can fix code that breaks in the next version of Rails while keeping the current version working as expected.

Now that we are using the dual boot technique, the next two steps should be fairly straightforward:

  1. Upgrade any gems/libraries that are not compatible with next version of Rails
  2. Fix test failures in the next version of Rails, ensuring that the current version of Rails works as expected

Once both sets of test suites are green, it’s time to wrap up the upgrade process:

  1. QA next version of Rails
  2. Use next version of Rails in production

Once the upgrade is finally done and the next version is being run in production, it’s time to finish the upgrade process - remove dual boot code and run post-upgrade tasks. We have an article to help you with that process:

  1. Finish the upgrade opens a new window

Conclusion

While it’s not the only way to upgrade, Rails upgrades can definitely be completed in increments. Upgrading in increments is a great way to address technical debt while still continuing day to day software development tasks.

Need help upgrading your Rails application? Talk to us today! opens a new window

Get the book