00:00:12.049
I'm here to talk about the history of upgrading a big Rails application to the latest version. This is a story of how Shopify managed to upgrade our monolithic Rails application to production. First, let me introduce myself. I am Rafael França, and you can find me on Twitter and GitHub as @rafaelfranca. I am a member of the Rails core team and work for Shopify as a developer. You may also know me because at every Rails conference, you'll see me in the Rails committee so I am also self-proclaimed as the Rails maintainer.
00:01:02.460
This talk is about how Shopify upgraded its application to a new version of Rails. Specifically, we started looking at Rails 5 because Shopify began around the same time as Rails itself. The initial commit of the Shopify codebase was in 2004, shortly before the first release of Rails. This means we’ve been using the same codebase for about 13 years.
00:01:40.920
As the timeline shows, Shopify follows the Rails releases very closely. For instance, after the release of Rails 2.0, Shopify upgraded shortly after. The same goes for Rails 3.0, but for Rails 4, it took us a bit longer to upgrade. We took about a year to upgrade to Rails 3.2 and maintained Rails 2.1 in the meantime because it was still stable for our application.
00:02:56.550
When it was time to upgrade to Rails 5, we started the process soon after its release in 2016. However, we only finished the upgrade by 2017. It took almost a full year to upgrade Shopify to Rails 5.0 from the previous version. Shopify is quite a large application—it’s the largest Rails application in production today, with over 374,000 lines of code. This number doesn’t even include any kind of stylesheet or JavaScript.
00:03:39.720
We also have more than 2,000 classes within our codebase, which contributes to a significant amount of complexity. Our test coverage is about 1.3 lines of tests for every line of code. It's important to note that Rails 5.1 is going to be a challenge, as we want to ensure our application continues to run smoothly.
00:04:45.430
So how do you upgrade a large application to Rails 5? In a straightforward situation, you would create a new branch and make all changes necessary to bring the application up to date. However, that's not our case. Shopify is a massive application, and we have hundreds of developers working on the same codebase every single day.
00:05:06.940
Upgrading to the latest Rails version while keeping everything functioning correctly is very difficult due to conflicts that may arise from code changes or the introduction of new bugs with every commit. We needed a strategy to utilize the same codebase with two different versions of Rails.
00:05:44.319
In our case, the best solution was to utilize a shared Gemfile. This approach allows us to run the same code with two different versions of Rails in both development and production environments. Implementing this solution is not overly complicated; it involves creating two different Gemfiles and using environment variables to manage dependencies.
00:06:49.360
We used conditionals in the Gemfile to determine which Rails version to use based on the current environment. This approach maintains the possibility of upgrades without the complications of trying to track changes across multiple files.
00:07:43.229
Eventually, we faced challenges with our testing setup. To get our tests to work correctly with both versions of Rails, we had to create a parallel Continuous Integration (CI) system that operated with Rails 4 and Rails 5 simultaneously. This way, we could ensure all changes were compatible.
00:08:45.780
During the upgrade, we encountered many dependency issues. It was essential that all dependencies worked with both Rails versions. Some dependencies required significant updates, which took time. One of our notable examples was upgrading the chain action page XML parser, which resulted in a more simplified codebase.
00:10:01.019
After upgrading the dependencies, the next task was fixing the numerous tests that had broken as a result of the upgrade. Our testing suite had thousands of failures. To manage this, we created a systematic process to address each failure.
00:11:55.830
One of the most significant challenges we faced during this process was around protected attributes in Rails controllers. The older way of handling these attributes changed significantly with Rails 5, requiring us to revisit how we managed model updating.
00:12:42.510
We had to ensure that sensitive fields such as user ID and passwords were only accessible when specifically allowed under certain conditions. This required adding a new method for attribute accessibility.
00:14:05.990
Another big change led to issues with working on controller tests, as the behavior of strong parameters changed between Rails 4 and 5. We had to update all our tests to ensure they were operating with the correct setup.
00:18:22.480
When we encountered issues with parameter handling, we found ourselves needing to upgrade our systems continuously. This upgrade process highlighted the importance of adapting our application to fit the changes in Rails.
00:19:58.199
The Rails 5 upgrade required significant code refactoring. Parameters were no longer inherited by default, which posed a challenge since many developers relied on this behavior.
00:21:50.219
As we wrapped up the upgrade and transitioned the application into production, we ensured that deprecated code was removed and compatibility layers were created to support the legacy features.
00:23:37.100
The objective moving forward is to keep Shopify aligned with the latest Rails versions while ensuring backward compatibility and minimal disruption to our users.
00:30:27.859
If anyone has further questions about our upgrade process or the changes made, I'm here to discuss and share insights. Thank you!