posted on October 14, 2015 in leeroy, project

Bringing LeeroyCI to the next level

LeeroyCI started out as an simple CI that gets out of your way and at the same time is powerful enough to cover the needs of small to medium sized organizations. And you can see that in some design decisions, like not using a database but only plain files and JSON. While LeeroyCI has proven to be the right tool for the job, it was lacking some features a „modern CI“(tm) should provide. Let me tell you about all the upcoming changes and why LeeroyCI will be better than ever while still being simple.

Before starting to add features I talked to other users I know of, in different company sizes. It ranged from start ups to mid sized agencies and the largest one I know of is a contractor for an airline (rest assured: not the critical stuff that keeps planes in the air). There are some setups I would not have imagined to see, the two most surprising being Xcode builds and .Net. There were some common pain points I wanted to address with the next release. To be able to do that it was time to ditch files and move to a database.

Choosing The Right Data Store

It is 2015. There are more data stores than you can possible remember (and/or imagine). And all of them, of course, solve all your problems, scale infinitely, disprove CAP, laugh at ACID and solve world hunger. Thankfully I only need to store a bit of configuration, jobs and results. So basically all of them work, without challenging their crazy marketing statements.

I would have preferred one that I can just integrate in Leeroy, like bolt, but all I found were either really complex to integrate, just simple key/value stores or had other shortcomings. So I took the easy way out: SQL - and to keep the dependencies as minimal as possible: SQLite.

The biggest inconvenience is that I now have to use the target platforms compiler toolchain to build a binary. So easy cross-compilation from OSX to Linux is gone. But since I already run Leeroy on a Linux box I just added a build step when all tests pass.

As for the ORM I decided to go with gorm. There will now be many devs reading this and think I am crazy for not using SQLx or using an "ORM" at all in Golang. But honestly? It works and it saves me time. And it is nicely encapsulated in model methods, if it ever gets in my way replacing it is stupidly simple.

The only open question is if I want to support different databases than SQLite. Currently the Postgres drivers are part of the developer branch, but I am not sure I'll keep them around. The advantage would be that you can reuse the database you eventually already have and you do not have to backup another file to keep your CI statuses. I also got a rough idea how to use a database to coordinate a farm of Leeroys, so you run one instance on Windows, one on Linux, one on OSX and point them to the same DB and viola: your builds only pass when all Leeroys report that the code is good.


Beside a new UI, which is still WIP, there are some nice features that will hopefully make your life easier. The UI will undergo a redesign once my fiancee got some free time. Meanwhile it should still be an improvement. To add assets and easily modifiable templates while only shipping one binary without any archive to extract I added rice.

Search, Rerun and Cancel

You are now able to search for a branch or commit.

You can rerun previous jobs. Have a race condition in your tests you did not fix yet but a failed build is blocking your deploy? Just rerun the tests, cross your fingers and question yourself for not fixing the tests.

Got the same branch scheduled 5 times? Need to get a production build out and you do not want to wait for other tests to finish? Cancel everything that is in your way - as long as it is not running.

new interface

Admin Interface

The biggest visible change is likely the admin interface. You can now configure commands, notifications, repositories through your browser. In 2015. Isn't it amazing?! Jokes aside: After introducing the database and user accounts this was the next logical step to make using Leeroy simpler.

But we are still not there yet. Configuring a notification for example is still a bit ugly.

A command still relies on a script stored on the CIs instance. One of the next things to do will be moving the build, test and deploy scripts to the database.

But overall the admin interface should help everyone getting started with LeeroyCI while still not getting in the way if you configure the 10th repository.


You can not connect via a websocket and get all events pushed to your client. At the same time I introduced the concept of access keys. I implemented a POC to show how it works in practice.

It is a native OSX app, written in Swift, which shows a notification when an event happened. The next step will be filtering by the email address of the commit author. From there this could turn out to be quite usable.

Parallel builds

Leeroy can now also run builds in parallel. The default configuration is 1 build at a time, but it can easily be changed in the admin interface. This is a two edged sword. Running builds in parallel can be nice, but it also adds a bit complexity. If you are using Django e.x. you have to make sure your test script uses a different database for each test runner. To support this LeeroyCI now passes a third argument to the build script, a number indicating which internal task number the build got. In your build script you can now just change the environment variable for the database - you are using an environment variable and don't hardcode, right? - and you are good to go.

Leeroy will not build the same branch in parallel. This is a limitation to not increase the complexity of the way deployments are handled. I am not sure if this will change in future, it most likely depends on the feedback I get.

Next Release

There are a few things I have to take care of before merging the current development branch into master. I want to improve the test coverage a bit and use websockets to refresh the browser to see when a build is done and hopefully add some UI improvements.

In its current state the development branch should be stable. We are using it at FlightCar and I am using it privately, as well as 3 other companies who made the transition. I do not think you will see any surprises when you migrate, but if you prefer to only use production releases you have to wait for another week or two.

I would love to talk to you about this post, your ideas or awesome projects.

I am @fallenhitokiri on Twitter and GitHub or you can send me a mail.