Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / PowerShell
Technical Blog

Cake Build Tool

Rate me:
Please Sign up or sign in to vote.
4.92/5 (12 votes)
20 Feb 2018CPOL3 min read 32.8K   23   9
The Cake build tool is a build tool that utilizes the Roslyn (compiler as a service) from .NET.

I don’t know exactly when or where I first came across the Cake build tool, and at the time I made a mental note to look at it in more detail (as I am not a massive fan of MSBuild). That time came and went, and I did nothing about it. Then Cake came across my radar again so this time I decided to dig into it a bit more.

So What is this Cake Build Tool?

The Cake build tool is a build tool that utilizes the Roslyn (compiler as a service) from .NET. What this means is that you can write very precise build scripts using very familiar C# language syntax that you know and love.

Getting Started

The best way to get started is to clone the example repo: https://github.com/cake-build/example

The repo is a simple C# class library and a test project all within a single solution.

image

As you can see, this project is very simple. What we would like to do with this project is the following things:

  • Clean solution
  • Restore Nugets
  • Build solution
  • Run tests
  • And also have ability to push out Nuget package (nupkg file)

Most of this is already available within the example repo: https://github.com/cake-build/example, with the exception of pushing a nuget package at the end.

What Bits Do You Need to Run a Cake Build?

So what do you need to provide to run a cake build?

You just need these 2 files:

  • build.ps1 (bootstrapper that doesn’t change, grab it from repo example above)
  • build. cake (this is your specific build and should contain the targets/tasks you need for your build)

The .cake File

As the build.ps1 is a standard thing, I won’t worry about that, but let's now turn our attention to the build.cake file which for this post looks like this:

PowerShell
#tool nuget:?package=NUnit.ConsoleRunner&version=3.4.0

//////////////////////////////////////////////////////////////////////
// ARGUMENTS
//////////////////////////////////////////////////////////////////////

var target = Argument("target", "Default");
var configuration = Argument("configuration", "Release");

//////////////////////////////////////////////////////////////////////
// PREPARATION
//////////////////////////////////////////////////////////////////////

// Define directories.
var buildDir = Directory("./src/Example/bin") + Directory(configuration);

//////////////////////////////////////////////////////////////////////
// TASKS
//////////////////////////////////////////////////////////////////////

Task("Clean")
    .Does(() =>
{
    CleanDirectory(buildDir);
});

Task("Restore-NuGet-Packages")
    .IsDependentOn("Clean")
    .Does(() =>
{
    NuGetRestore("./src/Example.sln");
});

Task("Build")
    .IsDependentOn("Restore-NuGet-Packages")
    .Does(() =>
{
    if(IsRunningOnWindows())
    {
      // Use MSBuild
      MSBuild("./src/Example.sln", settings =>
        settings.SetConfiguration(configuration));
    }
    else
    {
      // Use XBuild
      XBuild("./src/Example.sln", settings =>
        settings.SetConfiguration(configuration));
    }
});

Task("Run-Unit-Tests")
    .IsDependentOn("Build")
    .Does(() =>
{
    NUnit3("./src/**/bin/" + configuration + "/*.Tests.dll", new NUnit3Settings {
        NoResults = true
        });
});


var nugetPackageDir = Directory("./artifacts");
var nuGetPackSettings = new NuGetPackSettings
{   
  OutputDirectory = nugetPackageDir  
};

Task("Package")
  .Does(() => NuGetPack("./src/Example/Example.nuspec", nuGetPackSettings));


//////////////////////////////////////////////////////////////////////
// TASK TARGETS
//////////////////////////////////////////////////////////////////////

Task("Default")
    .IsDependentOn("Run-Unit-Tests");

//////////////////////////////////////////////////////////////////////
// EXECUTION
//////////////////////////////////////////////////////////////////////

RunTarget(target);

There are a couple of concepts to call out there:

  • We have some top level arguments/ variables
  • Nice C# features that we have used before
  • We have Tasks just like other build systems. We can make one task depend on another using .IsDependantOn(“”)
  • There seems to be wide range of inbuilt things we can use for example these guys below. These are all prebuilt items in the cake DSL that we can make use of. There are loads of these, the full list is available here: https://cakebuild.net/dsl/
    • CleanDirectory
    • NUnit3
    • NuGetPack

Have a look at the DSL web site - there are quite a few cool things you can use:

image

Running the Build

So with this build.cake and build.ps1 (bootstrapper file) in place, we would like to run the build. Here is how we do that:

  1. Open PowerShell window as Administrator
  2. Issue this command in PowerShell: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
  3. Change to the correct directory with the .cake file in it, and issue this command : .\build.ps1
  4. You should see some output, where it eventually completes
  5. You should also see a tools folder

This is the tail end of the build I just ran above.

image

And this is the sort of thing that we should see in the tools folder that the cake build created.

image

Deploying a Nuget

So I stated that I also wanted to be able to deploy a Nuget Package as a Nupkg. To do this, I need to create the following .nuspec file for the Example project.

XML
<?xml version="1.0"?>
<package >
  <metadata>
    <id>Example</id>
    <version>1.0.0</version>
    <title>Cake Example</title>
    <authors>Sacha Barber</authors>
    <owners>Sacha Barber</owners>
    <licenseUrl>http://github.com/sachabarber</licenseUrl>
    <projectUrl>http://github.com/sachabarber</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Simple Cake Build Tool Example</description>
    <releaseNotes>1st and only release</releaseNotes>
    <copyright>Copyright 2018</copyright>
    <tags>C# Cake</tags>
  </metadata>
  <files>  
   <file src="bin\Release\Example.dll" target="lib\net45"></file>  
</files> 
</package>

So with that in place, we can also try the Nuget publish Task that our build.cake file has in it like this:

  1. Open PowerShell window as Administrator
  2. Issue this command in PowerShell: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
  3. Issue this command in PowerShell: .\build.ps1 -Target Package

After running that, we should see artifacts folder with the following artifact in it:

image

Conclusion

I was pretty happy with this, I went from not using Cake at all to carrying out ALL my requirements in 1 hour on a train ride with limited WiFi. It just seems to work, and I imagine it would be a good fit for working with something like https://about.gitlab.com/.

I think I will be looking to use this little build tool a lot more.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2016
  • Codeproject MVP 2016
  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
QuestionInteresting Pin
RickZeeland20-Feb-18 22:09
mveRickZeeland20-Feb-18 22:09 
AnswerRe: Interesting Pin
wkempf21-Feb-18 7:51
wkempf21-Feb-18 7:51 
NewsRe: Interesting Pin
RickZeeland21-Feb-18 8:03
mveRickZeeland21-Feb-18 8:03 
GeneralRe: Interesting Pin
wkempf22-Feb-18 2:20
wkempf22-Feb-18 2:20 
GeneralRe: Interesting Pin
RickZeeland22-Feb-18 4:08
mveRickZeeland22-Feb-18 4:08 
GeneralRe: Interesting Pin
Sacha Barber21-Feb-18 19:05
Sacha Barber21-Feb-18 19:05 
GeneralRe: Interesting Pin
wkempf24-Feb-18 4:04
wkempf24-Feb-18 4:04 
QuestionThe Cake is a Lie Pin
wkempf20-Feb-18 10:59
wkempf20-Feb-18 10:59 
AnswerRe: The Cake is a Lie Pin
Sacha Barber20-Feb-18 18:03
Sacha Barber20-Feb-18 18:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.