Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
I’ve used various build systems for compiling, testing and deploying .NET based applications. TFS, VSTS, AppVeyor, TeamCity have had one thing in common. They all contained the configuration of my build, test and deploy pipeline in their system with no way to extract it.Build as Code
Removing the build steps out of your build system and turning into code has two major benefits to me:- Build Anywhere: Once you have a build script, you should be able to execute and build it anywhere. No longer are you relying on the build server and it’s build steps which are specific to that build system.
- Source Control: Since you build is now in code, can can live right along side your application in source control. This means that if you have the source, you have the build script.
Cake?
Cake (C# Make) is a build automation tool for .NET. It allows you to write C# to run various Tasks that you would likely find as build steps on your build server. Such as compile code (msbuild), run unit tests (xunit, nunit, mstests), creating nuget packages, create deployments via Octopus Deploy and a pile more.Getting Started
It’s really easy to get started using Cake. I’ve created a demo which is available on GitHub. It contains a basic Hello World application along side the Cake script described in the rest of this blog.Video
If you prefer watching a video tutorial, I’ve added a video that outlines the same content as this blog.Build Script
First thing you need to do is get the Cake build script that is written in PowerShell. From your project folder, run the following command to download the latest PowerShell Ssript (build.ps1)Invoke-WebRequest http://cakebuild.net/download/bootstrapper/windows -OutFile build.ps1
Cake Script
Next we need to create our Cake script. This script will define all the build tasks that the PowerShell Build Script (build.ps1) will execute. Create an empty file “build.cake” in the same directory along side the build.ps1. I recommend using VS Code along with the Cake extension to create and edit your build.cake file.Build
In this my demo application, I have a CakeDemo.sln that I’m going to build. it contains two projects, CakeDemo and CakeDemo.Tests which has an xUnit test. In our build.cake, let’s setup our first task to run MSBuild on our solution. Above we define a task named “Default” which calls MSBuild. Then to invoke Cake by calling RunTarget specifying our default task. Now we can run our build.ps1 powershell script which will execute our build.cake C# script. You can see that Cake downloaded some packages from NuGet which it requires to run the build, compiled our build.cake, and then executed it and its tasks (MSBuild). If we take a look in our bin\ directory, we can see all the build output files.Running Tests
There are many different types of tasks you can define in your cake script. Take a look at all the built-in API’s. A common task you may perform is running Unit Tests. In my Demo I have a project with an xUnit test. We can run the xunit console test running from our cake script as well. The fist thing we do is tell Cake we need an external tool from NuGet. In our case we need the xunit console runner. At the top of our build.cake script, add#tool "nuget:?package=xunit.runner.console"Now we can add a task to run our xunit tests. I’m going to modify our script a bit further in order to separate our compiling using msbuild and running our xunit tests into separate tasks. You can tell Cake which tasks are depend on on others. In this example, our xUnit task is going to be dependent on a build. Let’s execute our build script again and see the output of our build and the xUnit console runner.
This is interesting but I’m not seeing the benefit to it aside from the “you don’t need a separate tool [aside from powershell] to run a build” factor. I would argue that the compile/build tool is intrinsic to a given system’s development and maintenance so it’s a reasonable expectation to require it on any given platform.
We use NAnt for our build recipes (which gives us C# capabilities in the script engine). All build steps are in the NAnt script which is in source control so it lives with the projects. We use Jenkins to orchestrate our integration and release builds which basically just call NANT targets and OctopusDeploy to manage environment deployments. The build, deployment and integration concerns are clearly separated.
Ultimately you would invoke the cake build.ps1 from your build server. Exactly like you are doing now with Jenkins and NAnt. The Cake script would contain all the tasks for building, testing, and invoking Octopus Deploy. The only thing the build server (Jenkins, TeamCity, etc) would be used for is pulling code from source control, then invoking Cake.
did you use Cake in Windows for building, testing ? any good patterns and practices in a real world sample using Cake and all tasks for Builiding ? any full source code Cake tasks about building , how invoke Cake ?
I’ve always using LinqPad to build/deploy projects for the same reasons, but I’ll have to give Cake a look!
Thanks so much for the great article. I’m still trying to figure out cake, but this article was very useful.
I just wanted to point out though(unless I’m missing something) that the file next to `build.ps1` should actually be `build.cake` instead of `cake.build` as stated in the article.
Ooops! Thanks for pointing out the error. For some reason when I was writing the blog post I kept typing it backwards. The post has been fixed. Thanks again!
Hi, great article.
What I need to do in order to set up cake on a close environment without internet connection.
Thanks