The first step of any robust development workflow relies on a structured and well-defined build process. Having a manageable build process can spare your development team from wasted time, headaches and unnecessary complexity. If you're handling a handful of projects with low compilation overhead, this particular topic might be irrelevant to you. Today's article is mainly targeted for those who must work with multiple projects, of different kinds (Web applications, Scheduled tasks, Console applications, Mobile application, database script, so on) and deploy multiple artifact types.
Before we jump in to my suggestion, just keep in mind that your build strategy might have an impact on your deployment workflow. Always be aware of artifact inter-dependencies, versioning, parameterization and deployment requirements. Ideally artifacts should be self-contained (should not require any external dependencies) however sometimes that's not always the case. Besides of the typical environment dependencies like (as an example) requiring Windows Server 2012 R2, .Net Framework 4.5.1, Web Deploy 3.5 and IIS with URL Rewrite installed, some other artifact interdependencies might exist, like (another example) adding a particular set of DLLs to the global assembly cache GAC before enabling a set of scheduled tasks. My point is, try to fully understand your artifact dependencies, be aware of the deployment workflow and adapt your build process to make your provisioning and deployment processes as simple as possible. However, today I'm just going to focus on the build process.
As far as I'm aware, most development teams rely on proprietary build management systems to define their build process (examples: TeamCity, Bamboo, TFS, Jenkins). However, build definitions setup in this systems are not inter-changeable, meaning that you can not setup a build definition in TeamCity and later on move it to Bamboo. To be honest, most of the time this is not an issue. Let's be real, how many times do you expect your build system will change? Nonetheless, another approach might be desirable. So what if all build definitions could live right beside your code? On top of retaining history of all build definition changes, developers could easily debug build issues without needing access to a build agent and quickly modify build definitions, on their branch, without interfering anybody else's work. Obviously my previous arguments could be seen as negatives since you're giving more power to the developers, which might be a bad idea depending on how disciplined they are. Don't get me wrong, sometimes too much power can be problematic.
Now, what do I have to propose? Cake-Build! As it is self-described "Cake (C# Make) is a cross platform build automation system with a C# DSL to do things like compiling code, copy files/folders, running unit tests, compress files and build NuGet packages.". In other words you can write C# to manage your build tasks, so your build definition is fully written in C#! Isn't that awesome!? To get started I would recommend following their getting started guide. If you're looking for something even quicker, follow this steps:
- Copy the 3 required files to root of your repository:
- Open build.cake in a text editor and search-and-replace all "./src/Example.sln" entires to match your *.sln location (always use forward slashes)
- Open PowerShell, navigate to the root of your repository and execute build.ps1
Simple right? This should be enough to get you started. For the next steps I suggest reading the "Fundamentals" section in the getting started page and install Cake's Visual Studio Code extension to edit *.cake files. I know this is a bit raw, but should be enough to spike your interest. Seriously give it a try and let me know what do you think.