Using Cake with VSTS or TFS

Introduction

This guide uses functionality available in Cake 0.17. Check back after 0.18 is released for more exciting TFS/VSTS news!

Cake has always included enhanced support for a huge range of CI build providers, and as of v0.17.0, this now extends to the Team Foundation Build (TF Build) engine used by both Visual Studio Team Services (VSTS) and Team Foundation Server (TFS)!

Environment Information

While you could always use the built-in EnvironmentVariable aliases to pull information about the build environment, this quickly becomes messy and feels a bit hacky to me. Now, we've added first-class support for the environment variables used by the TF Build engine. What does this mean? Well, it means you can easily make tasks only run when running from VSTS or TFS:

Task("CI-Build")
.WithCriteria(TFBuild.IsRunningOnVSTS || TFBuild.IsRunningOnTFS)
.Does(ctx => Information("Hello from Team Foundation Build!"));

Build information

You can also "natively" grab build information like the build name or the user who requested the build:

var buildName = TFBuild.Environment.Build.Number;
var user = TFBuild.Environment.Build.RequestedFor;

Agent Information

If you want to have your script more aware of the build environment it's running in, you can also pull agent information.

For example, if the cloud agents provided by Microsoft are missing an optional dependency, you could skip tasks on hosted agents:

Task("On-Prem-Only")
.WithCriteria(!TFBuild.Environment.Agent.IsHosted)
.Does(ctx => Information("This task won't run on cloud agents"));

Conversely, you may want more information about what agent is in use for on-premises agents:

Task("Agent-Info")
.WithCriteria(!TFBuild.Environment.Agent.IsHosted)
.Does(ctx => {
	Information("Hostname of the current agent is {0}", TFBuild.Environment.Agent.MachineName);
	Information("The current agent in TFS/VSTS is named {0}", TFBuild.Environment.Agent.Name);
	Information("The agent is installed into the {0} directory", TFBuild.Environment.Agent.HomeDirectory);
});

Alternatively, you can also grab the various "special" directories used by the agent:

Task("Directories")
.Does(ctx => {
	var work = TFBuild.Environment.Agent.WorkingDirectory;
	var buildRoot = TFBuild.Environment.Agent.BuildDirectory;
)};

Build Definition

We can also easily get information about the build definition this build belongs to:

Information("Build from definition {0} with the ID {1} and revision {2}",
	TFBuild.Environment.BuildDefinition.Name,
	TFBuild.Environment.BuildDefinition.Id,
	TFBuild.Environment.BuildDefinition.Version
);

Repository and project information

TFS even provides us information about the team project and source control repository currently in use by the build. There's rather a lot of information available for this, so make sure to check the documentation.

Information("Current repository name: {0}", TFBuild.Environment.Repository.Name);
Information("Repository is of type {0}, currently in branch {1}", TFBuild.Environment.Repository.Type, TFBuild.Environment.Repository.Branch);
Information("Building source version {0}", TFBuild.Environment.Repository.SourceVersion);

or for team project info:

Information("Build belongs to team project '{0}' with ID {1}",
	TFBuild.Environment.TeamProject.Name,
	TFBuild.Environment.TeamProject.Id
);

Summary

As you can see, these properties provide a convenient and structured way to pull information about the current build environment whenever you're running from a VSTS or TFS environment. Check back soon for some awesome new features for TF Build users coming in Cake v0.18!