Pimp My Jenkins — Continuous Delivery Dashboard Edition
At FOODit, we try to be smart about bringing on additional pieces of developer infrastructure and the maintenance that comes along with them. Setting up local websites and servers on Mac Minis in closets is decidedly fun and allows you to rapidly plug a hole, but over time the hacks add up and it becomes time-consuming to manage. As people come and go, it’s often not fully handed off and, inevitably, turns into an unmanageable mess. Often, core business processes depend on a machine under someone’s desk for which no one remembers the password.
A few months after I joined FOODit, I was tasked with building a dashboard to track continuous delivery. In the spirit of the company, I was asked to do it entirely in the cloud and without adding any new servers or machines, if possible. It sounded like a bit of a challenge, but nevertheless, I was excited to give it a try.
So the idea for the product, as communicated to me, was a way to track changes and features as they progressed from ‘in development’, to ‘released’, to ‘production’ and all of the phases and steps in between. The visualization was a series of columns representing each step in the continuous delivery process. The board showed the status of which tasks were in development, being tested, ready for release, and deployed and when different transitions began.
When tasked with building this dashboard, someone suggested the crazy idea of hosting the whole thing using nothing but Jenkins.
For the back-end, the idea was that you could pretty easily build a REST API with Jenkins. Triggering a job is analagous to making a REST API call for POST and PUT or refreshing the cache for a GET call. The result of the call would be saved as a Jenkins build artifact. The job you trigger can perform whatever tasks it needs to, using whatever programming language you prefer and then generate a JSON response as an artifact.
For the front-end, the HTML and JS for the dashboard is stored as an artifact to a Jenkins job as well and we could use the same Angular frameworks that we use on our consumer facing products. A Jenkins job simply builds the site (using grunt) and saves all the HTML and JS as artifacts. A great bonus is also that since these pages are hosted on Jenkins the authentication flow solves itself.
For the database, Jenkins has jobs that generate all the relevant data for the dashboard. Whenever a pull request is opened or a commit is made to a branch, Jenkins is normally called to run unit tests - at the same time we also save out an artifact that generates a list of pull-requests and branches. Our deployments are handled by promoting builds in Jenkins, and with each promotion we update an artifact that has a list of which build is on which environment.
For real-time communication, there were some Jenkins-only means to solve the problem, but we ended up using a free Firebase account to simplify the code.
The Finished Product
The Finished product looks like this:
In the 6 months since the dashboard was created, the team now has a better grasp on what’s going on. In the past, there was much confusion as to whether or not a feature had been released, which build was on which environment, and who was working on what. All of this was accomplished without adding an additional server, website, or hack.