Deconstructed CI services
Continuous integration is a common practice in the industry and it’s effectively a baseline requirement for continuous delivery. Every commit should automatically trigger a build that will check the code, run automatic tests and eventually deploy the current state of the application for further testing or even to your production environment.
Right now, there are many cloud-based CI services available that are easy to set up. These are sound solutions when you’re starting a project. At the other end of the spectrum, for bigger and more complex projects, there’s usually already some tooling set up on-premise and specially configured for the needs of your project. Jenkins is a common choice.
Recently, a new breed of CI services has emerged. These split the traditional monolithic CI system into parts, some of which run in the cloud, making them easy to set up. Others can run elsewhere, giving you a finer control over your builds. They effectively deconstruct the CI system into two main parts. First up, orchestration – coordinating with your source code repository and deciding what to build and when. And runtime – actually performing the build, testing, and deployment jobs.
Two of these next gen CI services have caught our attention – Buildkite and GitHub Actions. Buildkite is based on two concepts. Pipelines describe the steps and actions you’d like to execute (managed as code in your codebase). Agents are build runners that will poll the jobs that need to be executed from the orchestration engine at buildkite.com.
You can manage your set of agents directly, run jobs on your own infrastructure, and scale as much as you want. If you need to make more builds, you can just increase the number of agents picking them up. This also means your code never has to leave your network. Pipelines can be defined as static files, saved in your repository, but they can also be dynamic templates. It gives you great flexibility in the ordering of your builds. In our case, in a monorepo we can only build what is needed and independent tasks can run in parallel.
GitHub Actions were introduced during the last GitHub universe and are still in beta. You can define workflow of actions triggered by events on your repository and actions are then executed inside Docker containers of your choosing (described as Dockerfile). Workflows can be created with a visual editor or directly edited as text files, using a subset of the HCL language used by Terraform, for instance. This makes it really easy to build small blocks of operations and tests on your repository orchestrated by the workflow.
There are already many existing open source actions that can be reused in your project, making it easier and faster to set up your own workflow. Unlike Buildkite, Github Actions don’t, at the moment, give you control over where or how these actions will be executed – they run on GitHub’s runtime.
The common theme in these new services is the understanding that a runtime to run CI jobs isn’t that different from a runtime to run your service. And it should really be decoupled from the triggering of jobs and orchestration of what runs in which order. We expect the trend to continue, leading to more flexible, scalable and cheaper-to-operate continuous delivery automation.