Build System vs CI System: What's the Difference and Why Does it Matter?
What's a build system? And what's the different between a build system and CI? In this article, we explain the 'build system vs CI' question and how CI servers play a part.
A bit of History First, Young Fellas
I personally equate build systems to Continuous Integration systems. At least, I do so nowadays. I probably wouldn't 20 years ago. We are, after all, comparing two sides of the same coin; a problem that has been present in software development since forever! Just kidding. The term 'build system' started becoming popular in English literature around the 60s:
That's around the time software started becoming a thing and mainframes were being set up at company HQs with cranes! No customers enjoyed interacting with software. CD pipelines were just a dream and no one spoke about lead time, deployment steps, or even releases.
Dave Farley, Jez Humble, Dr. Nicole Forsgren, and all the leading figures that have changed the way we think about CD tools and CD processes weren't even born. Software development practice was a craft under development, then compilers, transpilers, and all the raging tech of the day was being created. At least, the very first versions of what build tools would look like eventually.
But then, new stuff came rolling down the timeline. Version control was likely the best new thing to land in anyone's dev environment. Continuous Integration was arguably the second category in software development that reached a certain maturity in the naughts, according to Google. Applications were becoming first-class citizens in any organization, open source was exploding, and build servers were becoming an utter annoyance. Hence, we got modern / mature CI systems to toughen the software development process with ongoing automation to a previous manual process.
Not a NIST Definition, But Here We Go: Build System vs Continuous Integration (CI)
We want to explore two terms that, for many, are synonymous - and yet, the actual point of this debate is not so much whether they mean the same thing, but rather, how devs want to use them.
The hard line dividing both concepts is that a build system refers to a tool (or set of tools) that usually runs locally on the developer's machine. Continuous Integration, although initially just a daemon running in the background polling the source code repos looking for change to trigger a process, now roughly equates to a set of best practices by which developers frequently merge code changes into a central repository where automated builds and tests run. We won't bore you too much with this, but if you want to read up on the benefits of Continuous Integration and want to know, what is CI, we do have an article for you.
The interesting bit is, as always, in the details. The nuance behind build systems is the isolation to which developers tend to gravitate to. I say this without passing any judgment: coding requires a high level of abstraction and enormous amounts of focus and concentration, which are better catered to when a machine is finely-tuned to the desires of the developer. Main branch, feature branches, configuration files, etc. are a lot to handle. Locally, all dependencies are well-controlled, the IDE is personalized to the specific workflows the developer most likes, etc. But that work, even at its productivity peak, will only end in fast builds but few integrations, which eventually cascades into a merge conflict horror in enterprise-level developer teams. That's not the coding philosophy any company wants since communication speed and integration frequency are too slow and prone to conflicts with longer periods of resolution.
That's exactly the reason why CI became such a successful part of continuous delivery (CD) methodologies. The concept, championed by Kent Beck in Xtreme programming, popularized by Martin Fowler in an article in 2000, and later revised and updated in 2006, had its first implementation in a CI tool in Cruise Control (developed by Thoughtworks).
The build system remains at the core of any CI system, but modern CI systems de-incentivize Continuous Build, Occasional Integration (CBOI) practices and foster collaboration, frequent integration, constant code review, and many best practices that, ultimately, benefit software quality, security, and the velocity and trust of development teams. The beauty of CI is that the system (or at the very least, the necessary bit for the developer to be confident changes won't break anything (i.e. their microservice)), can be completely spun up, integrated with the changes, and ran through syntax, tests, scanners, and so on to return a sanity check to the user to deliver the artifact.
Ultimately, the difference boils down to the Integration bit. A Continuous approach refers to the characteristic of a system that is in a constant state of readiness to run a process (think: small changes on a daily basis, or multiple times per day, as opposed to weekly or monthly). But what does Integration really mean? The most shallow definition would include running integration tests. That is, the ability to know if the code from different teams or individuals is breaking the overall functionality the codebase in itself is meant to deliver. Integration in this context also includes high-level syntax checks, linting, and some sort of static code analysis.
Cut to the Chase: Why Is this Important?
Whether you have a build system or a CI system with CI Servers, or whether you are truly doing Continuous Deployment through CI (or more likely, CBOI) is mostly irrelevant. As creators, developers want to focus on their work. For that to happen, they need to be served a pipeline: something that, regardless of it running locally or shared in a public cloud instance with their team members, is instantly and conveniently provided when needed.
The configuration needs to be either democratized - or even completely abstracted - in a self-serve way. Traditional CI systems like Jenkins failed at this and overloaded devs and build engineers with tons of Groovy code that looked at changed directories or repositories the way the old daemons used to do. You can read our article on the Dependency / Integration Hell that is Jenkins for more thoughts on that.
The long and short is, this doesn't scale in a big org where many engineers have to edit these files where repo structures are complex, and where governance and access to said IP is critical to their business. Instead, CI sits at the core of what modern software development teams want: a platform, meaning the layer on top of a cloud native setup, that allows DevOps to set baseline pipelines and devs to self-serve what they need from it.
CBOI is also the symptom of something much bigger that goes beyond the engineer's natural habit to work in isolation. Spinning up the whole system and making it go through all required checks and scans is not a feat every infrastructure can work with. Queues and slow builds / a slow software delivery process will be the most frequent outcome. But even if feasible, the economic tradeoffs of running the complete system and its tests every time is incredibly costly. If you practice good old TDD with your new features, your test suite will only increase and your build process will get chunkier. New code will become more expensive to run (which sort of goes against all attempts to lower costs) in the software build farm, regardless of it running in a local environment or in the public cloud. Compute, networking, and storage charges will - dare we say - get chonky.
CI is thus too about learning from repeating patterns. After all, a CI pipeline is something that is repeated over and over again, most of the time with incremental changes only, and ultimately, with the least of those changes going to the production environment. QA teams and their testing environment are overloaded and the best CI systems out there include intelligent capabilities able to detect only what has changed and apply the tests required to that subset of the code.
Eventually, teams realize that the way to go is to settle on and maintain a proper developer experience. Whether your developers are running everything locally in their own build systems or collaborating through a shared CI server might not be the actual problem.
As this paper points out, developers want to make an impact. They want their hard work to contribute to a solution. For that, the system they use needs to provide feedback on how their contributions are being delivered to the end user. It’s the confidence that this feedback mechanism provides that really encourages developers to become empowered and reach velocity. Quoting the research piece, “developer[s] will deliver less frequently if the delivery processes are time-consuming, if it’s too complicated to deliver, or if there is no evident value in delivering often to the mainline.”
So that’s why Harness is built the way it’s built. Among other things, to provide a solid developer experience. One that shortens the length of the feedback loops between code committed to code validated and updated. With this in mind, the engineers and designers at Harness are building a CI/CD platform (plus feature flags, cloud cost management, and additional products) that boosts developer confidence and abstracts complexity - all while lowering risk. We'd love to invite you to try Harness today.
If you're not ready to take the plunge yet, feel free to continue your reading journey by reading about the best CI tools, or simply learning more about the Harness Continuous Integration platform.