John Jago

My upload script is 176 times faster than Travis CI

For the longest time, I used Travis CI to run builds on my code and perform actions like deploying this blog. I don’t remember how exactly I first came across it, but it was probably because Travis CI was one of the few solutions out there at the time.

Fast forward to today, I went on there to see if I had any projects still using Travis CI, and what do you know, new website! Apparently they had been acquired two years ago by a company called Idera, which seems to be in the business of acquiring developer tools that are going out of business. I didn’t even know.

I had switched this blog from being deployed through Travis CI to using a small shell script that I run manually.

I switched because once in a while the builds would fail for random reasons, and it took unreasonably long for something that I know can run much faster.

I could tolerate the failed builds, but I could not tolerate waiting 5 minutes for something that should take seconds.

There were many hoops to jump through for code being deployed through Travis CI. The code would be pushed to GitHub, then Travis CI would take however long it needs to detect the new commits, then it would spin up a virtual machine, clone the repo, run the Hugo binary, which I had to include in this repo, and finally run my deploy script. All the authentication between the pieces also took some time.

Last but not least, it always had the nerve to fail builds right before they are done, saying

pgrep: invalid user name: john

which I could not figure out how to fix, but I at least was able to make it not fail.

It averaged about 37 seconds per build. Not bad, but 21.8 times slower than it is with my own script, which for today’s blog post took 1.7 seconds.

What was it doing the other 4 minutes? I don’t know.

I wrote a shell script, and in about 30 lines of Bash, including comments and empty lines, this blog deployed in about a second. At the core, the script does the same stuff that Travis CI did. That is, build the static site and transfer the files to a remote server, and a little bit of cleanup.

Although I have to run it manually (and it would be trivial to make it run on every commit using Git hooks), it feels so good to get rid of everything else in the way of doing the actual work. Running it manually is not even that big of a problem since I update the site infrequently. The upside is that my changes are live seconds after I run the script. I don’t have to sit around for 5 minutes waiting for Travis CI to start my build. I see the results right away.

I have to admit that GitHub Actions is way faster than many of these older CI tools, but there’s just something about having 30 lines do all the work that makes it feel so robust and maintainable. The only dependencies are the Hugo binary installed on my computer, rsync, and the shell itself. There’s no Go Docker image, no lines of Ruby (Travis CI) between GitHub and the end result.

When I run this script I know it will work and that it will be fast, and I’ve found that people generally like those two things.