Getting Ready for Rails 6.0: How to Dual Boot
In this article I will explain how you can dual boot your application in your local environment and your CI server. I hope that this will help you get ready for the next stable release of Rails.
Even though my example assumes you are running Rails 5.2 and want to migrate to Rails 6.0, these tips work for any two versions of Rails.
Create a Gemfile.next File
In his talk he mentioned quite a handy companion gem:
ten_years_rails. I'm going to use that gem to get my project ready for dual
booting. First, I need to install it in my local environment.
$ gem install ten_years_rails Successfully installed ten_years_rails-0.2.0 Parsing documentation for ten_years_rails-0.2.0 Installing ri documentation for ten_years_rails-0.2.0 Done installing documentation for ten_years_rails after 0 seconds 1 gem installed
ten_years_rails requires Ruby 2.3 or higher. You can find a manual
Now that I can use that gem, I will initialize my
Gemfile.next file like this:
$ 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
That command creates a
Gemfile.next symlink to my
Gemfile and adds an util
method to my
# Gemfile def next? File.basename(__FILE__) == "Gemfile.next" end source 'https://rubygems.org' # ...
If you have any problems installing
ten_years_rails, you can manually add the
next? method to your
Gemfile and create a symlink like this:
$ cd path/to/project $ ln -s Gemfile Gemfile.next
Bump Rails (Gemfile.next)
In this simple example, I only need to upgrade
rails (from Rails 5.2 to Rails
6.0). It's very likely that you will have to upgrade more dependencies. My
Gemfile now looks like this:
def next? File.basename(__FILE__) == "Gemfile.next" end source 'https://rubygems.org' if next? gem 'rails', '~> 6.0.0' else gem 'rails', '~> 5.2.3' end # ...
Now I can install my current dependencies with
bundle install and my future
next bundle install. If
next bundle install doesn't work
for you, you can just run
BUNDLE_GEMFILE=Gemfile.next bundle install. As a
general rule, if
next <command> doesn't work in your environment you can
replace it with
next bundle install, I have a brand new
That means that my dependencies are ready to run my test. So I can run them like
$ next bundle exec rake
The main advantage of using dual booting your Rails application is that you
can run your tests with two different versions of Rails. Running
bundle exec rake
still works thanks to the conditionals in your
Setup Continuous Integration
Both samples will require you to commit and push
Gemfile.next to your repository;
will run a build matrix; and might need some tweaking.
For all of our client projects we prefer this continuous integration service. Here is the configuration that you could use for dual booting in Circle CI:
A few notes about this configuration:
- It's using Ruby 2.6 and a Postgres database
- It's using Circle CI's API version 2.0
- It has a lot of duplication (there is probably a way to DRY it)
- The key is to configure a workflow with two jobs (one for Rails 5.2 and another one for Rails 6.0) like this:
workflows: version: 2 build: jobs: - "build-rails-5-2" - "build-rails-6-0"
For all of our open source projects we prefer this continuous integration service. Here is the configuration that you could use for dual booting in Travis CI:
A few notes about this configuration:
- It's for an open source application that is using Postgres
- You might not need some of the things in this sample
- It's certainly simpler than the Circle CI configuration. I love how simple it is to configure a build matrix in Travis CI:
rvm: - 2.2.6 gemfile: - Gemfile - Gemfile.next
Start Fixing The Rails 6.0 Test Suite
Now that you have your test suite running in both Rails 5.2 and Rails 6.0, you can start tweaking your code and dependencies to work with both gemfiles. There will be two big hurdles:
- Getting Bundler to bundle your dependencies
- Getting your test suite to pass
This has been quite a useful technique for us at fastruby.io. We have used it with client projects, internal projects, and open source applications.
I hope that you will find it useful in getting ready for the upcoming Rails 6.0 stable release.