Cake v0.28.0 released

Published
Thursday, May 31, 2018
Category
Release Notes
Author
devlead

Version 0.28.0 of Cake has been released.

We're really excited by this release which has some splendid features and improvements!

In this blog post we'll highlight:

  • Typed context
  • Setup context
  • Criteria messages
  • "Potentially breaking"
  • Issues & workarounds

Contributions were included from:

Typed context

In previous versions of Cake you've had to rely on global variables or static members to share variables/state between tasks; this leads to unnecessary complexity and hard to maintain code.

In this release we have introduced the concept of typed context, where in the Setup method you can create and return a class; this object is then available to be used in Teardown method, Task actions and criteria.

The class can be any C# class, as it's just standard C# you can provide get & set for properties you want to be mutable, and only get for read only properties.

public class MyBuildData
{
	public string Configuration { get; }
	public bool SignAssemblies { get; }
	public bool AssmbliesSigned { get; set; }

	public MyBuildData(
		string configuration,
		bool signAssemblies)
	{
		Configuration = configuration;
		SignAssemblies = signAssemblies;
	}
}

Providing your script with a typed context is done by returning an instance of a class from your script Setup method.

Setup<MyBuildData>(setupContext =>
{
	return new MyBuildData(
		configuration: Argument("configuration", "Release"),
		signAssemblies: BuildSystem.IsRunningOnAppVeyor);
});

Accessing your data in your task action and criteria, is then done by supplying a type parameter to your task Does / DoesForEach / WithCriteria methods.

Task("Sign")
    .WithCriteria<MyBuildData>((context, data) => data.SignAssemblies)
    .Does<MyBuildData>(data =>
{
      data.AssmbliesSigned = true;
});

And it's then done in a similar way with your script Teardown method.

Teardown<MyBuildData>((teardownContext, data) =>
{
    if (data.AssmbliesSigned)
    {
        Information("Assemblies were signed");
    }
    else
    {
        Information("Assemblies were NOT signed");
    }
});

Setup context

This release changed the script Setup context from a ICakeContext to ISetupContext. In addition to everything that ICakeContext offers, there is now some additional information provided:

ICakeTaskInfo TargetTask { get; }
IReadOnlyCollection<ICakeTaskInfo> TasksToExecute { get; }

TargetTask is the task that initiated the script and TasksToExecute are the tasks that will be executed based on the dependency graph of the target task. Access to which tasks actually will be executed has been a greatly sought after feature, combined with the typed context makes it fairly straightforward to enable some advanced scenarios.

Setup<MyBuildData>(setupContext =>
{
	var signAssemblies = BuildSystem.IsRunningOnAppVeyor
							|| StringComparer.OrdinalIgnoreCase.Equals("Sign", setupContext.TargetTask.Name);

	var isPublishBuild = setupContext
                          .TasksToExecute
                          .Where(task => StringComparer.OrdinalIgnoreCase.Equals("Publish", task.Name))
                          .Any();

    return new MyBuildData (
    	configuration: Argument("configuration", "Release"),
    	signAssemblies: signAssemblies,
        isPublishBuild: isPublishBuild);
});

In the above code we choose to sign assemblies if either running on AppVeyor or the script initiating target is Sign. And we'll treat build as a "publish" build if any of the depending tasks is named Publish.

Criteria messages

Task WithCriteria can now have a message that's outputted when a task is skipped, this will make it clearer in the log why a specific task wasn't executed.

This means by doing

Task("Sign")
    .WithCriteria<MyBuildData>(
        (context, data) => data.SignAssemblies,
        "Sign skipped because SignAssemblies is set to false."
        );

the verbose output goes from

========================================
Sign
========================================
Skipping task: Sign

to

========================================
Sign
========================================
Skipping task: Sign skipped because SignAssemblies is set to false.

Potentially breaking

When we have to ship a breaking change in Cake, one piece of feedback that we have often heard is that it can be very frustrating to have a build suddenly fail, due to a new dependency on a higher version of Cake.Core. We have always advocated that all builds should be pinned to a specific version of Cake, so that a new breaking change does not affect your builds, however, we also understand that some people want to run their builds this way.

In this release we've introduced the notion of a "Potentially breaking change", which is when we've refactored code we will not break the build, but issue a warning but not break the build.

image

In the case that we find that a change will break addins, then we'll issue a hotfix and then set the minimal required version of Cake.Core and break the build.

This means even though we made some substantial changes, version 0.28.0 will still have 0.26.0 as the minimal required version for Cake addins to target.

We believe this compromise will minimize end user frustration - while still keeping the risk of runtime errors low.

Issues & workarounds

In this release we've refactored some internals of Cake, while most scripts with just continue to work without issue, there are some that will need to be tweaked.

  • CakeTaskBuilder<ActionTask> has been refactored to CakeTaskBuilder, this means scripts that use and store CakeTaskBuilder<ActionTask> like i.e. Cake.Recipe will need to replace all instances of CakeTaskBuilder<ActionTask> to CakeTaskBuilder.
  • ActionTask is removed in favor of just using CakeTask, this to reduce complexity and simplify future features.
  • ICakeContext interface now has a ICakeDataResolver Data property that needs to be implemented.
  • Setup as gone from Action<ICakeContext> to Action<ISetupContext>.

Full details of everything that was included in this release can be seen below.

As part of this release we had 6 issues closed.

Feature

  • #2008 Allow defining a typed context to be used throughout a Cake script.
  • #1772 Provide access to the run target and ordered list of tasks.
  • #1594 Add overload to WithCriteria which prints a message.

Improvment

  • #2163 Update to Roslyn 2.8.x packages, adding support for C# 7.3.
  • #2171 Add potential breaking change warning.
  • #2174 Support multiple Setup / Teardown.

Documentation

  • website#520 Formatting issues with examples in XmlPoke documentation