6 Reasons to use a Build System

TL;DR: Build systems are much more than a locally running copy of Jenkins, VSTS or TeamCity. Actually, both can be used in combination to provide the best CD/CI experience.

Full disclosure: I’m the author of a build system myself.

Build automation is one of my favorite topics. In this article I’d like to share a few reasons, why using a build system can be of great benefit. To make things clear, I’m not advocating for using a build system at all costs. It is basically a matter of complexity, project size and future growth. Certainly, I wouldn’t setup a build for a simple console application that will never reach 500 LOC. For mid-scale projects, simply using Jenkins or TFS might also fit perfectly. However, a complex web application with several services involved, that needs to run tests in parallel, requires setting up various scheduled tasks as well as publishing artifacts and packages to various endpoints — that is something that I would definitely support with a strong build system in place. Roslyn and Nodatime are good examples for repositories with complex builds.

Let’s get to the point why I appreciate build systems:

Cross-platform: build scripts can be executed on any operating system by using one of the available runtimes (.NET CLR, Mono, dotnet CLI). Build systems usually ship with dedicated bootstrapping scripts based on either PowerShell or Bash for easy invocation. The build implementation is not duplicated but remains consistent in one language. Portability: build scripts are invoked with just a single command on any machine. You may lose the convenience of several wizards provided in Bitrise, TravisCI or AppVeyor, but you’ll also gain the power of switching them easily. Build servers are still indispensable; for instance for parallelization, investigation mechanisms or historical statistics. Troubleshooting: build scripts usually consist of multiple build steps, which depend on each other. Build systems often allow to execute single steps without their dependencies to track down issues very efficiently. Attaching the debugger and inspecting variables is an additional luxury. Also the feedback cycle is much quicker compared to build servers — you don’t need to wait until your build is scheduled, plus you won’t occupy the agents for others. Versioning: build scripts can change as often as any other code. Therefore it’s meaningful having them committed in CVS along with the rest of your project. This also ensures that older revisions can be built at any time, and that major build modifications can be tested in isolated branches. Extensibility: build scripts are much easier to grasp and extend compared to implementing Bitrise steps, TeamCity plugins or VSTS extensions. If you pick the right build system that even matches your main project language, pretty much everyone on your team will be able to understand and manage the build. Control Flow: build scripts inherently support various kinds of control flow mechanisms like if-statements, foreach- and while-loops. On a build server with fancy wizards, how would you iterate over a bunch of NuGet packages and push them to different sources, depending on their root namespace? I have no idea. But it’s quite easy with a build system.

I hope these thoughts sound reasonable.

Choose your weapon

Looking at the modern .NET ecosystem, we have some great alternatives:

The following graphic depicts the growth of popularity of these frameworks:

Star History of related GitHub Repositories

Happy building!