Skip to main content

Build Anatomy

A build project is a regular .NET console application. However, unlike regular console applications, NUKE chooses to name the main class Build instead of Program. This establishes a convention and allows easier navigation in your solution. The Build class must inherit from the NukeBuild base class and define a Main method to invoke the build execution and define any number of default targets:

class Build : NukeBuild
public static int Main() => Execute<Build>(x => x.Compile);

// Target definitions

You will learn how to write target definitions in the next chapter.

Base Properties​

The NukeBuild base class offers great insight into your build through various properties.

Build Environment​

Properties related to the build environment provide information about where the build is running and where various files are located:

abstract class NukeBuild
static Host Host { get; }
static bool IsLocalBuild { get; }
static bool IsServerBuild { get; }

static AbsolutePath RootDirectory { get; }
static AbsolutePath TemporaryDirectory { get; }

static AbsolutePath BuildAssemblyFile { get; }
static AbsolutePath BuildAssemblyDirectory { get; }
static AbsolutePath BuildProjectFile { get; }
static AbsolutePath BuildProjectDirectory { get; }

With the Host property you can determine the running environment, for instance with Host is TeamCity. Make sure to explore other implementations of the Host base class through your IDE.

Since Host, IsLocalBuild, and IsServerBuild are static properties, you can conveniently use them in static conditions to skip targets (including their dependencies) in local or server builds.


Learn more about the AbsolutePath class and how it's used for path construction.

Build Status​

Properties related to the build status allow you to examine the status of your targets and the overall build:

abstract class NukeBuild
IReadOnlyCollection<ExecutableTarget> InvokedTargets { get; }
IReadOnlyCollection<ExecutableTarget> SkippedTargets { get; }

bool IsSuccessful { get; }
bool IsFailing { get; }
bool IsFinished { get; }
int? ExitCode { get; set; }

IReadOnlyCollection<ExecutableTarget> ExecutionPlan { get; }

IReadOnlyCollection<ExecutableTarget> ScheduledTargets { get; }
IReadOnlyCollection<ExecutableTarget> RunningTargets { get; }
IReadOnlyCollection<ExecutableTarget> AbortedTargets { get; }
IReadOnlyCollection<ExecutableTarget> FailedTargets { get; }
IReadOnlyCollection<ExecutableTarget> SucceededTargets { get; }
IReadOnlyCollection<ExecutableTarget> FinishedTargets { get; }

You can examine the status of targets by using any of the appropriate ICollection<ExecutableTarget>. For instance, to check if a target has failed, you can write FailedTargets.Contains(MyTarget). This pattern is especially useful with dynamic conditions.

Build Events​

For implementing cross-cutting concerns, like telemetry and similar, you can hook into various build events:

abstract class NukeBuild
virtual void OnBuildCreated();
virtual void OnBuildInitialized();
virtual void OnBuildFinished();

virtual void OnTargetRunning(string target);
virtual void OnTargetSkipped(string target);
virtual void OnTargetFailed(string target);
virtual void OnTargetSucceeded(string target);