Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choice for build tool: MSBuild, NANT or something else?

Tags:

msbuild

tfs

nant

I am doing automation in my company. We are a C# workshop. Currently I am working on automated build. NANT is flow control tool. While NANT is not actively developed (last binary released on June 2012 and github repo is not active), MSBuild is better. Therefore, I prefer MSBuild but retiring NANT is still questionable - what is the cost?

I have come up with some pros and cons, but I know collective intelligence is better. Thanks for your help!


Update: I have read the question, but the second answer rises a concern for me. On build machine there are multiple .NET frameworks, will it be troublesome?


MSBuild

Pros:

  • Commercial support
  • Community is growing
  • Intergrated with VS and TFS
  • Keep pace with .Net

Cons:

  • Rewrite current script
  • Not familiar by people

NANT

Pros:

  • Already in use
  • Familiar by people

Cons:

  • Not updated for a long time (since 2012)
  • Community is not active
  • Lack of new .Net support
like image 585
CSakura Avatar asked Nov 30 '16 14:11

CSakura


2 Answers

We wrote FlubuCore (rewrite of Flubu). It's an open source C# library for building projects and executing deployment scripts using C# code.

Main advantages of flubu that I see are:

  • .Net Core support.
  • Easy to learn and to use because you write build script entirely in C#.
  • Fluent interface and intelisense.
  • Quite a lot of built in tasks (compile, running tests, managing iis, creating deploy package, publishing nuget packages, executing powershell scripts...)
  • Write your own custom c# code in script and execute it..
  • Run any external program or command in script with RunProgramTask.
  • Reference any .net library or c# source code file in buildscript. Now also available option to reference nuget package in build script.
  • Write tests, debug your build script..
  • Use flubu tasks in any other .net application.
  • Web api is available for flubu. Useful for automated deployments remotely.
  • Write your own flubu tasks and extend flubu fluent interface with them.

You can find flubu on nuget:

Search for FlubuCore.Runner if u need it for .net project

Search for dotnet-flubu if u need it for.net core project

Example of how flubu is used in .net:

protected override void ConfigureBuildProperties(IBuildPropertiesContext context) {
 context.Properties.Set(BuildProps.NUnitConsolePath,
  @ "packages\NUnit.ConsoleRunner.3.6.0\tools\nunit3-console.exe");
 context.Properties.Set(BuildProps.ProductId, "FlubuExample");
 context.Properties.Set(BuildProps.ProductName, "FlubuExample");
 context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
 context.Properties.Set(BuildProps.BuildConfiguration, "Release");
}

protected override void ConfigureTargets(ITaskContext session) {
 var loadSolution = session.CreateTarget("load.solution")
  .SetAsHidden()
  .AddTask(x => x.LoadSolutionTask());

 var updateVersion = session.CreateTarget("update.version")
  .DependsOn(loadSolution)
  .SetAsHidden()
  .Do(TargetFetchBuildVersion);

 session.CreateTarget("generate.commonassinfo")
  .SetDescription("Generates common assembly info")
  .DependsOn(updateVersion)
  .TaskExtensions().GenerateCommonAssemblyInfo()

 var compile = session.CreateTarget("compile")
  .SetDescription("Compiles the solution.")
  .AddTask(x => x.CompileSolutionTask())
  .DependsOn("generate.commonassinfo");

 var unitTest = session.CreateTarget("unit.tests")
  .SetDescription("Runs unit tests")
  .DependsOn(loadSolution)
  .AddTask(x => x.NUnitTaskForNunitV3("FlubuExample.Tests"));

 session.CreateTarget("abc").AddTask(x => x.RunProgramTask(@ "packages\LibZ.Tool\1.2.0\tools\libz.exe"));

 session.CreateTarget("Rebuild")
  .SetDescription("Rebuilds the solution.")
  .SetAsDefault()
  .DependsOn(compile, unitTest);
}

//// Some custom code
public static void TargetFetchBuildVersion(ITaskContext context) {
 var version = context.Tasks().FetchBuildVersionFromFileTask().Execute(context);

 int svnRevisionNumber = 0; //in real scenario you would fetch revision number from subversion.
 int buildNumber = 0; // in real scenario you would fetch build version from build server.
 version = new Version(version.Major, version.Minor, buildNumber, svnRevisionNumber);
 context.Properties.Set(BuildProps.BuildVersion, version);
}

Example of how flubu is used in .net core

public class MyBuildScript : DefaultBuildScript
{
    protected override void ConfigureBuildProperties(IBuildPropertiesContext context)
    {
        context.Properties.Set(BuildProps.CompanyName, "Flubu");
        context.Properties.Set(BuildProps.CompanyCopyright, "Copyright (C) 2010-2016 Flubu");
        context.Properties.Set(BuildProps.ProductId, "FlubuExample");
        context.Properties.Set(BuildProps.ProductName, "FlubuExample");
        context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
        context.Properties.Set(BuildProps.BuildConfiguration, "Release");
    }

    protected override void ConfigureTargets(ITaskContext context)
    {
        var buildVersion = context.CreateTarget("buildVersion")
            .SetAsHidden()
            .SetDescription("Fetches flubu version from FlubuExample.ProjectVersion.txt file.")
            .AddTask(x => x.FetchBuildVersionFromFileTask());

        var compile = context
            .CreateTarget("compile")
            .SetDescription("Compiles the VS solution and sets version to FlubuExample.csproj")
            .AddCoreTask(x => x.UpdateNetCoreVersionTask("FlubuExample/FlubuExample.csproj"))
            .AddCoreTask(x => x.Restore())
            .AddCoreTask(x => x.Build())
            .DependsOn(buildVersion);

        var package = context
            .CreateTarget("Package")
            .CoreTaskExtensions()
            .DotnetPublish("FlubuExample")
            .CreateZipPackageFromProjects("FlubuExample", "netstandard2.0", "FlubuExample")
            .BackToTarget();

    //// Can be used instead of CreateZipPackageFromProject. See MVC_NET4.61 project for full example of PackageTask
    //// context.CreateTarget("Package2").AddTask(x =>   
             x.PackageTask("FlubuExample"));

         var test = context.CreateTarget("test")
            .AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests"))
            .AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests2"));   

         context.CreateTarget("Rebuild")
             .SetAsDefault()                 
             .DependsOn(compile, test, package);
}

}

Detailed presentation and documentation can be found here: https://github.com/flubu-core/flubu.core

You can find full examples here: https://github.com/flubu-core/examples

like image 153
Stan88 Avatar answered Nov 16 '22 00:11

Stan88


Thanks for all answers. We have decided to use Cake since we are a C# workshop.

like image 38
CSakura Avatar answered Nov 16 '22 01:11

CSakura