Kickstarter recently rewrote the scripts we use to manage local development environments with a focus on improving their reliability. I want to share the benefits of that project.
The main Kickstarter app has several system dependencies. Dozens of people work in the codebase each day.
We had a
script/bootstrap that theoretically managed all the dependencies and configuration to get a working development environment. But in practice it was neglected, confusing to use, and rarely fixed the problem blocking a developer.
In my past as a sysadmin, I often installed software by running
./configure && make && sudo make install. Those familiar with this process are used to having thousands of lines of logs fly by like a Hollywood hacking montage. When the process finishes, it’s not always clear if it succeeded or if you need to scroll up to the cryptic error message you’ll need to google.
That’s how our old
script/bootstrap was subconsciously designed. I thought it was helpful to be so verbose!
In retrospect, this was quite wrong. Having too much detail made problems harder to solve: team members would paste lines of output that they thought included the salient error but actually didn’t. People avoided running
script/bootstrap because they worried it would break more things. That skepticism was understandable because the output didn’t make it clear what the script was doing.
As we embarked on a mission to improve developer happiness and productivity with a next-gen bootstrap script, we had a few goals in mind:
- Make it fast: we want people to be comfortable running this as part of their daily workflow.
- Make it debuggable: if there’s a problem, point people in the right direction so it’s easier to address it.
- Make it reliable: running it should result in a working development environment the vast majority of the time.
The core of our solution was the kickstarter/laptop script to install common dependencies across Kickstarter projects. While the script is not designed to be useful outside Kickstarter, we kept it open source to acknowledge the Thoughtbot script it’s based on and to serve as an example for others.
We use the laptop script within particular Kickstarter projects by calling it from a
bin/dev script. These
bin/dev scripts can also perform additional project-specific bootstrapping.
These new scripts have been quite successful, slashing the amount of time developers spend debugging problems with their local environments.
Make it fast
Here’s what it looks like to run
bin/dev on our main codebase:
We printed the timestamp for ambient performance context. By making it easy to see how long each step takes, it keeps our focus on making the script fast for developer productivity. The whole script took 12 seconds.
Make it debuggable
Here’s what it looks like when the script crashes:
When things inevitably break, we give several pointers for what to try next next. The
reset option clears caches and re-installs some historically flaky tools.
bash -x is a nice trick to get verbose output that’s helpful for particularly gnarly edge cases. We also point you to the appropriate Slack channel for extra help.
Make it reliable
We made several tweaks to more robustly handle edge cases.
As an afterthought, we added some emoji to the output for fun. Incidentally, we made a consistent, branded output format. That format has become familiar and trustworthy.
Output that doesn’t end with the green checkmark is more clearly an error. The big green success indicators and red error indicators don’t leave people guessing if it worked.
In retrospect, having clear, consistent, terse output for the script was the single biggest improvement needed to gain the trust of developers using the tool.
It gave me a deeper appreciation for the value of design and consistent UX to make even a CLI tool more trustworthy and useful.
Special thanks to Thoughtbot for their laptop script and to Mike McQuaid for sharing how GitHub replaced Boxen with Strap.