DotNetBuild is a build system written in C#. A build system allows you to automate your work by scripting all repetitive actions into executable tasks.
Within the .NET eco-system builds are often automated with the help of MSBuild scripts. I have used MSBuild extensively during the last few years but I never had a lot of joy in writing MSBuild scripts. Using a markup language (XML) to create build scripts never felt right to me.
You're probably thinking now:
XML is so 90s. You should've used gulp! gulp is cool, new and fancy. JS for the win!
Yeah, I know and you're probably right. Gulp is a great tool. Anyway things are the way they are. So yes, I created a new 'Make', my apologies to Hadi Hariri
The reason I created this is twofold:
- Primarely, I wanted to be able to use a real programming languages (.NET ) instead of a markup language (XML) to create build scripts.
- It started off as an experiment and a technical challenge for myself, but I got some very positive feedback so I decided to publish it
Because DotNetBuild is built on the shoulders of a giant (the .NET Framework), we can write build scripts in a language we already know and benefit of the power and features the framework gives us.
There are several ways to writing DotNetBuild scripts. I prefer the fluent API that the scriptcs runner offers me. Here's an example:
var dotNetBuild = Require<DotNetBuildScriptPackContext>();
dotNetBuild.AddTarget("ci", "Continuous integration target", t
=> t.DependsOn("buildRelease")
.And("runTests")
);
dotNetBuild.AddTarget("buildRelease", "Build in release mode", t
=> t.Do(context => {
var solutionDirectory = context.ConfigurationSettings.Get<String>("SolutionDirectory");
var msBuildTask = new MsBuildTask
{
Project = Path.Combine(solutionDirectory, "DotNetBuild.sln"),
Target = "Rebuild",
Parameters = "Configuration=Release"
};
return msBuildTask.Execute();
})
);
dotNetBuild.AddTarget("runTests", "Run tests", t
=> t.Do(context => {
var solutionDirectory = context.ConfigurationSettings.Get<String>("SolutionDirectory");
var xunitExe = context.ConfigurationSettings.Get<String>("PathToXUnitRunnerExe");
var xunitTask = new XunitTask
{
XunitExe = Path.Combine(solutionDirectory, xunitExe),
Assembly = Path.Combine(solutionDirectory, @"DotNetBuild.Tests\bin\Release\DotNetBuild.Tests.dll")
};
return xunitTask.Execute();
})
);
dotNetBuild.AddConfiguration("defaultConfig", c
=> c.AddSetting("SolutionDirectory", @"..\")
.AddSetting("PathToXUnitRunnerExe", @"packages\xunit.runners.1.9.2\tools\xunit.console.clr4.exe")
);
The script above is a part of the DotNetBuild script I use to build DotNetBuild itself :). You can find the entire script here
If you know Gulp, this syntax will probably look very familiar.
Basically there are four ways to create DotNetBuild scripts
- ScriptCs - Fluent API
- ScriptCs - Without the fluent API
- Precompiled .NET assembly - Fluent API
- Precompiled .NET assembly - Without the fluent API
A cool thing about DotNetBuild is that it doesn't limit you to just one programming language to write your build scripts. If you're using scriptcs you can use any programming language that is supported by the scriptcs runtime (currently only C#, but I believe F# support is on its way). When using the precompiled .NET assembly you can use any programming language that compiles to a .NET assembly.
We have specific integrations for TeamCity and AppVeyor that send messages to your CI server so you'll get immediate feedback about what DotNetBuild is doing. DotNetBuild will automatically detect if it's being run from any of these CI servers, so there's no additional configuration required from your side.
You can launch your DotNetBuild script from your CI server by using a command line task. Checkout the appveyor.yml file in the DotNetBuild repo to see how I got my DotNetBuild scriptcs script working from within appveyor.
If you're using TeamCity, you can either use a command line task or you can use our DotNetBuild plugin for TeamCity. Currently the plugin only supports precompiled DotNetBuild assemblies. Support for scriptcs is still being developed.