Abandon Jenkins for Great Good!

December 9, 2018

CI and CD techniques are a part of all good happened to the software development. Having CI in place means better productivity and higher confidence in the result of the everyday work. Sounds kind of obvious, right? Well, let’s take a look at the dark side of the Moon.

Do you have a person on the team who occasionally curses Gradle or (and) Maven, Android SDK or (and) NDK? Maybe someone who knows everything about these weird Shell scripts you have in the repository? You know, the one who doesn’t like mentions about broken nightly builds, looks at the htop from time to time? Yeah, the tooling person. The fancy name nowadays is a Developer Experience Engineer. Right. The question is — do you want to be this person? No worries — I already know the answer.

Nope

This is fine. Not a lot of people want to be occupied with fighting constant fires. It is a special skill of knowing how things work, preferably from different angles — from Linux kernel IO API to VCS hooks. The development process involves a lot of tools and issues might arise from each one of them. Gradle compile times suffer? Need to profile, compare different Gradle versions, check build scripts, analyze Java and Kotlin compilers and find out that it was a Linux kernel feature or a SSD failure. Sounds fun, right? Don’t get me started on how much time these things consume. Imagine a weird code issue which takes hour after hour and multiply it by a factor of uncontrolled external tools and environments.

⚠️ I have to note this explicitly — I’m describing a situation related to small teams. Big companies have dedicated units to manage all of this and not a single person.

Some people might think it is cool to be that person — the only one who knows how the toolchain works. Well, it is really not.

I was this person and it felt… strange. One day I’ve caught myself on a realization that I hadn’t written a single line of product-related code for a week. That’s when I’ve started to question myself and the work I do. Does it really matter for the product or for my coworkers productivity? What is the point of all this? Can it be optimized without losing benefits?

The first part of the solution was rethinking UI tests. The second one was related to…

Jenkins

It is perfect for scalable environments. Open source, plugin system, both declarative and GUI configuration, artifacts storage, battle-tested, familiar across the board and so much more.

There is a catch though — someone has to maintain it. Even the simplest setup — with only a couple of plugins — will eventually break (after a minor version update of course).

Basically every plugin update might break something. At the same time it is hard to ignore them because a lot include Security Issue warnings. Frequent security issues is not a good sign for any more or less serious system, but we’ll leave it for now.

Oh, and do not forget that Jenkins needs to be run somewhere. Amazon AWS helps but still — someone has to maintain it. And there is no isolation out of the box. Need to cache something across jobs? Either install globally (and suffer consequences) or reinvent a Docker-driven wheel over and over again.

Jenkins is a DIY product — it is the main strength and the main weakness at the same time.

Delegate

Human nature pushes us to be responsible for our own lives. At the same time…

Human beings are generally not capable of managing more than six to ten people, particularly when things go sideways and inevitable contingencies arise.

— Extreme Ownership

The same can be applied to the tools we use. There is a limit on how many things a small development team can manage on its own without losing the primary goal — to improve the business value of a product.

Fortunately enough, talking about CI, there is a variety of options to delegate this task: Travis, Circle, Bitrise and more.

Bitrise

It was a natural choice for the team because it is the only service that works with Bitbucket Server (not the same thing as the cloud version). Interesting fact — Bitbucket Server support was added by an open source contributor. It is possible because Bitrise components are open source.

Pricing is reasonable. I like that the hardware configuration is not hidden away from customers. At the same time there is an opt-in for machines with better specs. For some reason a lot of services hide that kind of information and do not allow to upgrade the hardware. I was told that Linux machines are provided via Google Compute Engine. Amazon instances for Jenkins costed us $1000 a month, Bitrise costs $360 for basically the same hardware. Plus no human resources to support Jenkins!

Since Bitrise people understand that caching is important for shorter build times there is a multi-level configurable caching. For Android projects basically everything sdkmanager provides is bundled into the underlying Docker image — I haven’t seen a single issue with missing SDK packages. At the same time, it is possible to reuse files across builds, which can be adapted to include Gradle build cache, dependencies — you name it.

Of course the configuration is declarative and understandable. There is no need to be a DevOps to read it.

trigger_map:
- tag: "v*"
  workflow: release

workflows:
 release:
    steps:
    - git-clone:
        title: "Clone Git repository."
    - cache-pull:
        title: "Pull cache."
    - script:
        title: "Run."
        inputs:
        - content: "bash ci/jobs/release.sh"
    - deploy-to-bitrise-io:
        title: "Attach artifacts."
        is_always_run: true
        inputs:
        - deploy_path: "artifacts/"
        - is_enable_public_page: false

The transition from Jenkins to Bitrise was seamless. For a while we used both in parallel and after a month I’ve quetly shut down Jenkins with no consequences for the team.

Adapt

We stumble upon a lot of things every day. The tricky part is habit. Hitting the same thing over and over again eventually will become familiar. This can lead to unforeseen consequences — like using Jenkins when it is not really necessary. Do not be afraid to change things. Mutations and selection formed the human race as it is right now. Who said it cannot form the best workflow for the team?


Title is a reference to the wonderful Lean You a Haskell for Great Good!.


Thanks to Artem Zinnatullin for the review!