Software build automation sweetness: Getting started with Cake

Fancy some Cake?

While cakes in all their forms are usually a delicious treat, the Cake I’m referring to is a build automation system written in C#. Nonetheless, if you haven’t used Cake before I’m sure you’ll find it just as sweet an experience!

Let’s dive right in with a definition of Cake, taken from the official Cake website.

Cake (C# Make) is a free and open source cross-platform build automation system with a C# DSL for tasks such as compiling code, copying files and folders, running unit tests, compressing files and building NuGet packages.

If you don’t currently automate your software builds, or are looking for a more lightweight solution that is also flexible, Cake might just be the right tool for you. By automating your builds with Cake you will save lots of time and prevent costly mistakes that can be made all too easily when performing the same steps manually.

In the following sections, I’ll talk you through how to set up Cake and integrate it into Visual Studio. I’ll then show you how to get started with a template build automation script.

Setup

Cake comes in two main flavours; the Cake .NET Tool and Cake Frosting.

In this article, I am going to focus on the Cake .NET Tool which allows you to simply add one or more build scripts into your solution and Cake will look after the rest (with Cake Frosting you write your build logic in a .NET console application which has the advantage of IntelliSense and easy debugging).

Note that although Cake is a cross-platform build automation system this article is focused on how to set up Cake in a Windows environment. However, regardless of your operating system, many of the setup steps will still apply aside from the Visual Studio instructions.

Cake .NET Tool

The Cake .NET Tool is built on .NET Core and can be installed as a local solution tool using the following instructions.

Note that it’s also possible to use the .NET Framework version of Cake. If you want to use this approach instead of .NET Core, you can skip past this section and use the .NET Framework ‘bootstrapper’ which I mention later in the Bootstrappers section.

To install the tool, first of all, open your solution in Visual Studio and then open the Package Manager Console pane by going to View –> Other Windows –> Package Manager Console.

Now enter the following command to create a tool manifest file.

dotnet new tool-manifest

Following this, if you open your solution folder in File Explorer you’ll see that there is a directory named ‘.config’ containing a file named ‘dotnet-tools.json’.

Note that if you already had a tools manifest file as part of your solution you will receive an error when you execute the above command and can simply continue to the next step instead.

Next, you’ll want to install Cake as a local tool using the following command.

dotnet tool install Cake.Tool

Note that if you want to install Cake as a global tool instead, you can run the following command.

dotnet tool install Cake.Tool --global

This will allow Cake to be accessed via the command line from anywhere on your system and doesn’t require a tools manifest file to be created.

Now that Cake is installed as a .NET tool try running the following command.

dotnet cake

You should get an error that is similar to the following.

dotnet : Error: Bootstrapping failed for '<path-to-project>/MyApp/build.cake'.
At line:1 char:1
+ dotnet cake
+ ~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Error: Bootstra...pp/build.cake'.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

build.cake, line #0: Could not find script '<path-to-project>/MyApp/build.cake'.

The error message tells us that Cake is looking for a file called ‘build.cake’ which doesn’t currently exist.

We’ll fix this after we get some things set up within Visual Studio.

Visual Studio extension

Installing the Cake for Visual Studio extension is optional. However, it does provide several useful features such as syntax highlighting and Task Runner Explorer support. If you use Visual Studio I recommend following the steps further below.

Note that if you prefer Visual Studio Code there is a great official extension for it too.

Installation

To install the Cake for Visual Studio extension, follow the steps below.

Within Visual Studio go to Extensions –> Manage Extensions.

On the Manage Extensions dialog, type the term ‘cake’ into the Search box and a result with a description of ‘Cake for Visual Studio 2022’ should appear in the item list.

Press the ‘Download’ button and after a brief moment, a message will appear at the bottom of the Manage Extensions dialog indicating that Visual Studio will be modified after it is closed.

Press the ‘Close’ button to close the Manage Extensions dialog.

Now close Visual Studio and make sure all other Visual Studio windows are also closed. After a moment, the VSIX Installer dialog will appear.

Press the ‘Modify’ button to proceed with the installation of the Cake extension. After the installation has completed, press the ‘Close’ button to close the VSIX Installer dialog.

You can now launch Visual Studio again.

Benefits

So what does the Cake for Visual Studio extension give us?

The main features are as follows.

  • Cake build file recognition and syntax highlighting.
  • Task Runner Explorer support, accessible via View –> Other Windows Task Runner Explorer.
  • A new ‘Cake Build’ menu, accessible via Build –> Cake Build.
  • New Cake item templates.
  • New Cake project templates.

We’ll use some of these features in the following sections to make our life a little easier.

Bootstrappers

It’s quite common practice when setting up Cake to create a bootstrapper that makes sure Cake is installed along with any other required dependencies. In this case, the bootstrapper script will be called instead of running the Cake tool directly to kick things off.

Creation

The Cake for Visual Studio extension provides a shortcut for creating a template bootstrapper script.

To access this feature, on the Visual Studio menu bar go to Build –> Cake Build –> Install a bootstrapper –> .NET Tool runner PowerShell.

Note that if you want to use the .NET Framework version of Cake instead of .NET Core, you can select the ‘.NET Framework runner Powershell’ option instead.

Selecting the runner option will create a ‘Solution Items’ folder within your Visual Studio solution, along with a ‘build.ps1’ file. This PowerShell script sets a few environment variables, restores any tools listed in your tools manifest, and then invokes the Cake tool.

Note that the .NET Framework PowerShell script has to do a lot more bootstrapping than the .NET Core script. This involves downloading files and restoring packages from NuGet etc. Therefore a bootstrapper is more or less essential when using the .NET Framework version of Cake.

Execution

You can run the bootstrapper PowerShell script from the Package Manager Console by running the following command.

./build.ps1

If you want to make it easy to run the script from File Explorer, I recommend that you create another file within the ‘Solution Items’ folder called ‘build.cmd’ and add the following contents to it.

powershell -File "./build.ps1"
pause

Now you can simply double-click on the ‘build.cmd’ file to kick off the build at any time.

You can remove the second line in the command file containing the pause if you don’t want the script to wait for a key to be pressed before exiting.

Build scripts

All of the setup work is now complete and we’re ready to create our first Cake build file.

It’s worth noting at this point that a lot of what I’ve talked through so far is not strictly necessary. To get started all you really need to do is install the Cake .NET Tool. However, I believe it’s important to get a complete environment set up that will make life easier going forward before getting into the details of how build scripts work with Cake.

With that said, let’s proceed to create our first Cake build script.

Add Build Script

The Cake for Visual Studio extension provides a convenient New Item template for creating a Cake Build Script.

If you’ve been following along you should already have a ‘Solution Items’ folder within your solution. If not, you can add this by right-clicking on the Solution node within the Visual Studio Solution Explorer pane and then clicking on Add –> New Solution Folder. I recommend specifying the name of the folder as ‘Solution Items’ by convention. However, you are free to call this whatever you like.

To create a new build script, right-click on the Solution Items folder and go to Add –> New Item…

On the Add New Item dialog, type the term ‘cake’ into the Search box and a result with a description of ‘Cake Build Script’ should appear in the item list.

Click on the Cake Build Script item and rename it to ‘build.cake’, then press the ‘Add’ button.

This will add a template build script to your solution.

Inspecting the build script

The contents of the template build script that is created, courtesy of the extension, are as follows.

///////////////////////////////////////////////////////////////////////////////
// ARGUMENTS
///////////////////////////////////////////////////////////////////////////////
 
var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");
 
///////////////////////////////////////////////////////////////////////////////
// SETUP / TEARDOWN
///////////////////////////////////////////////////////////////////////////////
 
Setup(ctx =>
{
    // Executed BEFORE the first task.
    Information("Running tasks...");
});
 
Teardown(ctx =>
{
    // Executed AFTER the last task.
    Information("Finished running tasks.");
});
 
///////////////////////////////////////////////////////////////////////////////
// TASKS
///////////////////////////////////////////////////////////////////////////////
 
Task("Default")
.Does(() => {
    Information("Hello Cake!");
});
 
RunTarget(target);

So what is this doing?

First of all, some terminology; ‘aliases’ are convenience methods that are built into Cake that help to make common build-related tasks easier to accomplish. For example, Information is an alias that provides a convenient way of outputting an informational message to the console.

Now onto the script code, in the ARGUMENTS section, two variables are initialised based on the value of arguments that are passed to the script from the command line. The first parameter of the Arguments alias is the name of the argument that is being read. The second parameter is the default value to use if an argument value was not specified. 

Note that the ‘configuration’ argument is not currently used in the script but is included in the template to help demonstrate how you can pass data into the build script from the outside. This configuration value could be used later when calling the built-in MSBuild alias, for example.

The SETUP / TEARDOWN section demonstrates the usage of the Setup and Teardown hooks where initialisation and cleanup tasks can be performed when the script starts and ends. In the template code, the Information logging alias is used to print some information to the console for demonstration purposes.

The TASKS section is where the actual build tasks are performed. The template code defines a Task named ‘Default’. The name of this task matches up with the default value of the target variable, resulting in this task being the first to be executed when the build script runs. A useful script will usually contain several different tasks. The Does method accepts an Action lambda containing the task logic. As per the Setup and Teardown hooks, the Information alias is used to print a message to the console.

The final line of code calls the RunTarget method, passing in the value of the target variable defined at the start of the script. This will cause the first task to execute, along with any other tasks that are chained to the first task.

Running builds

Now that we have Cake set up and a template build script in place, we can finally test it out!

Try running the following command again from the Package Manager Console.

dotnet cake

Alternatively, you can run the bootstrapper as follows.

./build.ps1

Or, open your solution folder in File Explorer and double-click the ‘build.cmd’ file.

In any case, the output of the build script will be similar to the following.

----------------------------------------
Setup
----------------------------------------
Running tasks...

========================================
Default
========================================
Hello Cake!

----------------------------------------
Teardown
----------------------------------------
Finished running tasks.

Task Duration
--------------------------------------------------
Setup 00:00:00.0188911
Default 00:00:00.0128244
Teardown 00:00:00.0019733
--------------------------------------------------
Total: 00:00:00.0336888

If you’re running the command to kick off the build from the Command Prompt or PowerShell you’ll get some nice syntax highlighting to indicate the success or failure of the actions performed.

Of course, this is only a sample script to get us started. The script doesn’t do anything useful right now; it’s up to us to add the custom logic required to carry out the sequence of build tasks we’d like the script to perform for us.

In my next article, I’ll demonstrate some really useful things you can get your build script to do for you. This will cover things like restoring NuGet packages, running MSBuild, and performing unit tests.

To get a flavour of what’s possible in the meantime, I recommend checking out the Cake DSL Reference page. From here you can browse through the various categories and explore all of the aliases (helper methods) which provide a great deal of functionality and help to simplify the process of automating your build process effectively.

Summary

In this article, I have focused on how to set up and get started with the Cake build automation system.

Cake is straightforward to set up, although there are a few different options in regards to how you run your build scripts that need to be considered. The option I’ve been covering has been the Cake .NET Tool as a lightweight and cross-platform runner.

I’ve walked you through how to set up Visual Studio so that it integrates nicely with Cake and I’ve shown you how to create a bootstrapper as a way of invoking Cake from your terminal.

Lastly, I’ve covered how to create a template build script and how to run it and view its output.

My next article will take things to the next level and show you practical examples of how you can use the power of Cake to automate your software builds effectively using built-in aliases.


I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂

Comments