Farewell ShipIt, Hello Merge Queue!
On a previous post on my block I talked about "ShipIt" a GitHub Bot we built when I was at Intuit to improve DevEx. Here I explain how achieve the same without any bot
The first time I faced a REPL console was back at university in the Languages and Programming Paradigms lecture by the great Casiano Rodriguez-Leon. We used the pry console, as it was nicer than Ruby’s built-in one irb. It was a really cool experience, as I was just able to type the code and run it. On top of that, the speed at which we were typing new code and figuring out what worked or didn’t was far higher than with the most common language we used at the university at the time, C++.
Although I’ve mentioned pry and ruby consoles, this tool is available in a wide range of languages, like python and even Golang! Though I think it’s most commonly used in Ruby and Python.
A read–eval–print loop (REPL), also termed an interactive top-level or language shell, is a simple interactive computer programming environment that takes single user inputs, executes them, and returns the result to the user; Wikipedia, Read–eval–print_loop
In other words, REPL consoles are very cool little pieces of software that lets you try things out and throw away the code afterwards.
Throughout time, I’ve seen these consoles used to test or build POCs and to try to improve developer experience, but they are sometimes used as a way to run scripts in production. At first, you might think that it is great as teams can easily use the production code to fix issues for users. No more getting into the database and updating data, you can use the DTOs you love so much allowing you to focus on developing your core features for the same users. But is it really that great? Let’s look a little deeper…
Do you need to fix some pesky data for your users, or do you want to do it behind the scenes to provide a great experience? Well just SSH in, run the console and do the migration! Easy-peasy-lemon-squeezy.
To me, this is one of the selling points to use a REPL console, you’re using your own code to fix issues, and no more random SQL migrations, or bringing up another repo with a quasi-identical code to connect to the database and run the scripts you need. If it’s not the same, most likely you’re forgetting something, and you might do more harm than good.
Sometimes, you need to adhere to a specific schedule and must respect a deadline. In my current gig, for example, banks have cut-offs at which you can no longer send files to move money around. So, if a piece of software fails, and you need to run a portion of it to finish the job and ensure your customers get paid, well you can!
With these consoles, you’re writing some “disposable” code that, most likely exists for the sole purpose of the task you’re currently working on and for which you haven’t tested the interactions with your system.
That means that this code and the risk assessment purely rely on your engineering team’s knowledge. It may be great today but, it might not be the case in the future.
Ideally, you should keep the code in your runbook but, in my experience, this is oftentimes not the case, and you’re rewriting similar code over and over again.
The code that you run on the consoles is not pushed to your VCS(Version Control System):
Sometimes, running your production code is not enough, and you are required to update some small portions of it to make it works for what you want to achieve. Ideally, you would change it permanently in the code, but, either it does not make sense for it to be a permanent change, or you can’t because you have made your code “so bad” that it’s impossible for you to cleanly execute the piece of code you need independently. This is not the fault of the consoles per se, but something noteworthy to say.
I have so many opinions about Monkey Patching alone that I’ll probably write something about it in the future.
DANGER, you might know this but Monkey Patching means all users accessing the same machine will see your change, so you should spin up other pods on which you should run the console instead. But if you’re running consoles as a common practice, you probably know this already, or you’re lucky enough to not have faced issues because of this (or you don’t know you have them now).
With consoles, you’re relying on the interpreter to yell at you when you’re doing things wrong, but sadly it can’t tell you whether your code passes other integration specs you might have failed if you had run your code against your test suite. Neither you’ll ask other peers for an opinion about such code, and worse even, if you’re not sharing such knowledge with peers in the code review cycle.
The industry already agreed tests and code reviews are necessary, why do I keep seeing teams following these bad practices then?
In my opinion, to fix problems properly, you need to face them to fix them for good. Patching things together works now, but it will get worse in the future.
At Intuit, our team had an internal API called the supportability API, that we used to run for special tasks or special migrations. It has several benefits:
Was it perfect? Nope! But it was serving us well. In retrospect, it would have probably been worth investing into something that would have allowed us to safely run internal APIs or to wire our database together without much integration involved.
Although this approach was keeping us on our toes, ensuring that we had good reusable code with clean patterns, and making the whole team aware of the changes we made to the codebase.
Should you use REPL consoles in production? No, in my opinion, you should not. They don’t allow your team to grow and fix the real issues about your codebase. It also allows you to be careless about the quality of your code, and you might end up being really coupled with them. In the end, instead of being a cool tool to allow you to move fast, it will likely become something that won’t let you move forward.
If your team uses these, please work together to move away from them:
I’d like to thank my wife Marie Dziubich for the help on this post (you definitely did not want to read the previous versions 🤣, although we are improving) and friends like Rubén Ángel Negrin Afonso with whom I’ve discussed this in the past.