构建工具的选择:MSBuild、NANT 还是其他工具?

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

我在公司做自动化。我们是一个 C# 研讨会。 目前我正在从事自动化构建。 NANT 是流量控制工具。虽然 NANT 没有积极开发(最后一个二进制文件发布于 2012 年 6 月 并且 github 存储库不活跃),但 MSBuild 更好。因此,我更喜欢 MSBuild,但淘汰 NANT 仍然值得怀疑 - 成本是多少?

我已经提出了一些利弊,但我知道集体智慧更好。感谢您的帮助!


更新: 我已经阅读了这个问题,但第二个答案引起了我的关注。 build machine上有多个.NET framework,会不会很麻烦?


MSBuild

优点

缺点


南特

优点

缺点

有一个 属性 nant.settings.currentframework 用于设置目标框架,以防您有多个 .net 框架

<property name="nant.settings.currentframework" value="net-2.0" />

As per .92 build:

  • nant.settings.currentframework 当前目标框架,eg. 'net-1.0'.
  • nant.settings.currentframework.description 已弃用。当前目标框架的描述。
  • nant.settings.currentframework.frameworkdirectory 已弃用。当前目标框架的框架目录。
  • nant.settings.currentframework.sdkdirectory 已弃用。当前目标框架的框架SDK目录。
  • nant.settings.currentframework.frameworkassemblydirectory 已弃用。当前目标框架的框架程序集目录。
  • nant.settings.currentframework.runtimeengine 已弃用。当前目标框架的运行时引擎,如果使用,例如。 mono.exe.

我们编写了 FlubuCore(重写了 Flubu)。它是一个开源 C# 库,用于使用 C# 代码构建项目和执行部署脚本。

我看到的flubu的主要优点是:

  • .Net 核心支持。
  • 易于学习和使用,因为您完全用 C# 编写构建脚本。
  • 流畅的界面和智能感知。
  • 相当多的内置任务(编译、运行 测试、管理 iis、创建部署包、发布 nuget 包、执行 powershell 脚本...)
  • 在脚本中编写您自己的自定义 c# 代码并执行它..
  • 运行 脚本中带有 运行ProgramTask 的任何外部程序或命令。
  • 在 buildscript 中引用任何 .net 库或 c# 源代码文件。现在也可以选择在构建脚本中引用 nuget 包。
  • 编写测试,调试构建脚本..
  • 在任何其他 .net 应用程序中使用 flubu 任务。
  • Web api 可用于 flubu。对远程自动部署很有用。
  • 编写您自己的 flubu 任务并使用它们扩展 flubu fluent 接口。

你可以在nuget上找到flubu:

如果您需要 .net 项目,请搜索 FlubuCore.Runner

如果需要,请搜索 dotnet-flubu for.net 核心项目

如何在 .net 中使用 flubu 的示例:

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.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);
}

.net core 中如何使用 flubu 的示例

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);
}

}

详细介绍和文档可以在这里找到: https://github.com/flubu-core/flubu.core

您可以在此处找到完整示例: https://github.com/flubu-core/examples

感谢所有回答。我们决定使用 Cake,因为我们是 C# 工作室。