
It’s been the topic of conversation in the Ruby community since before the release in December. If you’ve been writing Ruby for a while you’re likely aware of the difficulty with this particular upgrade. You may be reading this and wondering why it’s worth doing all this work and investing the engineering resources and time in the Ruby upgrade. Once we had fixed the warnings, we altered our monkey patch to raise errors in Ruby 2.7 which ensured that all new code going into the GitHub codebase was warning-free. Gems that were unmaintained were replaced with maintained gems. After a few months, coordinating with 40 teams, 30+ gem upgrades, and 11k warnings our CI build was 100% warning-free. We tracked warning counts in the Ruby 2.7 CI build to ensure that new code wasn’t introducing new warnings. This process helped us avoid duplicating work across teams and made it simple to determine ownership and status of each warning. **test suites that trigger these warnings** Line 16: warning: Using the last argument as keyword parameters is deprecated maybe ** should be added to the call They looked like this: - `app/jobs/delete_job.rb`

Our warning reports included the file emitting the warning, the warning itself, and the test suites that triggered the warnings. Once we had all the warnings processed, we opened issues for those teams with easy-to-follow directions for booting the application in the new Ruby version. We then parse warnings using CODEOWNERS and turn them into files that correspond to each owning team. The WarningCollector#process method stores all the warnings in a file called warnings.txt. Script = File.absolute_path("./././script/process-ruby-warnings", _FILE_)

join("*^.^*") # ascii art so we can split on it later. The patch stores the deprecation warning and the test path that caused the warning in a WarningCollector object which writes the warnings to a file and then processes them: class WarningsCollector < ParallelCollectorįile.open(path, "a") do do |message, origin|į.puts. Line = caller_locations.find do |location|

Here’s a simplified version of our monkey patch: module Warning To accomplish this we monkey patched the Warning module in Ruby. Since Ruby warnings are simply strings in the test output we needed to capture the deprecations and turn them into lists for each team to fix. Once we had the build running, we weren’t quite yet ready to ask other teams to help fix warnings. Due to how large our application is (over 400k lines!) and how many changes go in daily (100’s of PRs!), this drastically simplifies our upgrade process. It also made it easier for other engineering teams who needed to make changes to get their system running with the new Ruby version. This made it easy for us to make backwards compatible changes, merge those to the main branch, and avoid maintaining a long running branch for our upgrade. Just like we did with our Rails upgrade, we set up our application to be dual-bootable in both Ruby 2.6 and Ruby 2.7 by using an environment variable. In order to be successful we needed a solid strategy for sharing the work. Fixing that many warnings, some of which were coming from external libraries, takes a lot of coordination and teamwork. In order to run Ruby 2.7 deprecation-free, we had to fix over 11k warnings. It’s important to identify major changes early so we can evolve the application when necessary. At GitHub, we’re committed to running deprecation-free on both Ruby and Rails to prevent falling behind on future upgrades. With this release, future versions of Ruby will no longer accept passing an options hash when a method expects keyword arguments. Ruby 2.7 is a unique upgrade because the Ruby Core team has deprecated how keyword arguments behave. Many years ago, we ran GitHub on a fork of Ruby (and Rails!) and while that hasn’t been the case for some time, that experience taught us how important it is to keep up with new releases. For those who aren’t familiar with GitHub’s stack, we’ve been running on Ruby since the beginning. After many months of work, we deployed GitHub to production using Ruby 2.7 in July.
