【问题标题】:Choice for build tool: MSBuild, NANT or something else?构建工具的选择:MSBuild、NANT 还是其他?
【发布时间】:2017-04-14 21:41:10
【问题描述】:

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

我提出了一些优点和缺点,但我知道集体智慧更好。感谢您的帮助!


更新: 我已经阅读了这个问题,但第二个答案引起了我的关注。在构建机器上有多个.NET框架,会不会很麻烦?


MSBuild

优点

  • 商业支持
  • 社区正在成长
  • 与 VS 和 TFS 集成
  • 与 .Net 保持同步

缺点

  • 重写当前脚本
  • 人们不熟悉

南特

优点

  • 已经在使用中
  • 为人所熟知

缺点

  • 很久没更新了(2012年以后)
  • 社区不活跃
  • 缺乏新的 .Net 支持

【问题讨论】:

标签: tfs msbuild nant


【解决方案1】:

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

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

As per .92 build:

  • nant.settings.currentframework 当前目标框架,例如。 'net-1.0'。
  • nant.settings.currentframework.description 已弃用。当前目标框架的描述。
  • nant.settings.currentframework.frameworkdirectory 已弃用。当前目标框架的框架目录。
  • nant.settings.currentframework.sdkdirectory 已弃用。当前目标框架的框架 SDK 目录。
  • nant.settings.currentframework.frameworkassemblydirectory 已弃用。当前目标框架的框架组装目录。
  • nant.settings.currentframework.runtimeengine 已弃用。当前目标框架的运行时引擎(如果使用),例如。单声道.exe。

【讨论】:

    【解决方案2】:

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

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

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

    你可以在nuget上找到flubu:

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

    如果您需要 dotnet-flubu 用于 .net 核心项目,请搜索它

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

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

    }

    可在此处找到详细的演示文稿和文档: https://github.com/flubu-core/flubu.core

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

    【讨论】:

    • 看起来很有趣,有时间我去看看
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2011-04-21
      • 2021-12-25
      相关资源
      最近更新 更多