destroytoday.com

Upgrading to Ruby 2.7.1

Continuing my journey to modernize Cushion, I spent this weekend upgrading Ruby to the latest version (2.7.1) as well as updating a handful of other Ruby gems in the process. This is yet another situation where I’m forever thankful of Cushion’s test coverage. I can’t imagine upgrading Ruby, let alone a single gem, without running tests to automatically find anything that broke. Even then, at almost 6,000 tests, I’m still slightly concerned that something slipped through the cracks, so I wrote my own QA “certification” checklist to run through just to be sure that nothing serious broke in real world usage.

notion-qa-checklist

I ended up using Notion as a quick and easy way to write the QA checklist. I wrote a main checklist, then duplicated it for “certifying” the Ruby upgrade. I’d love to eventually explore integration tests to automatically cover these interactions, but I haven’t had a chance to dive into that yet. At the same time, even with tests, there can still be false positives or areas fail in the real production environment, so it’s better to play it safe with such a substantial change.

Shockingly, my unit tests were able to find only a single spot that broke between Ruby versions—BigDecimal. Cushion uses BigDecimal for handling currency (because don’t use floats), but between Ruby versions, BigDecimal is a bit more strict about the strings you can pass it. Cushion allows percentages for line item quantities, so you can say 50% of $1,000 for an upfront deposit, as an example. The code for this passed the entire `50%` string to BigDecimal, which played it cool before, but threw a fit with Ruby 2.7.1. Simply updating the code to extract only the number fixed the issue, and the rest of the tests passed with flying colors.

Aside from looking for bugs, I did find a few Ruby gems that I no longer use, so I was able to strip those out, too. Whereas my younger self was all about adding dependencies to cut the work in half, the wiser me, who is more experienced (also see “scarred”), is determined to remove as many dependencies as I possibly can. It’s shocking (but at the same time not surprising) to see how many dependencies end up abandoned. The repos’ GitHub issues lists end up full of questions from folks who all stumbled upon the same issues eventually. It’s also fascinating to see how many other people experience the exact problem I’m having only days before I searched for the solution.

The last point to mention with the upgrade is that Ruby 2.7 brings a slew of deprecation warnings with it that absolutely filled Cushion’s console. These are great to know to pinpoint the Ruby gems I still need to update, but I definitely don’t want these spamming my production console (and racking up my logging bill). After a quick google search, I realized that countless others experienced this same issue, so the fix was easy to find. Simply add an environment variable RACK_ENV=-W0, which keeps warnings out of the console. I’m slightly concerned that it might hide more than I’d like, but the other warning-specific solutions didn’t work for me, so I’m going to yolo this one.

In the end, the upgrade was delightfully uneventful—so far. It has given me a kick to continue updating dependencies, so I don’t find myself in the position where Cushion is tethered to a 10-year-old Ruby gem that prevents upgrading Ruby itself. Next up, however, is an update that has been a long time coming, ironically—Stripe. At one point, I did update the API version from the 2015-02-18 version to 2017-06-05, but that was years ago... literally three years, thanks to Stripe’s versioning. Luckily, Stripe is best in the biz when it comes to upgrading and docs, so I’m less worried about this one.