构建工具的选择: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
优点:
- 商业支持
- 社区在发展
- 与 VS 和 TFS 集成
- 与 .Net 保持同步
缺点:
- 重写当前脚本
- 不为人所熟知
南特
优点:
- 已经在使用
- 为人所熟知
缺点:
- 很久没更新了(自2012年)
- 社区不活跃
- 缺少新的 .Net 支持
有一个 属性 nant.settings.currentframework
用于设置目标框架,以防您有多个 .net 框架
<property name="nant.settings.currentframework" value="net-2.0" />
- 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# 工作室。
我在公司做自动化。我们是一个 C# 研讨会。 目前我正在从事自动化构建。 NANT 是流量控制工具。虽然 NANT 没有积极开发(最后一个二进制文件发布于 2012 年 6 月 并且 github 存储库不活跃),但 MSBuild 更好。因此,我更喜欢 MSBuild,但淘汰 NANT 仍然值得怀疑 - 成本是多少?
我已经提出了一些利弊,但我知道集体智慧更好。感谢您的帮助!
更新: 我已经阅读了这个问题,但第二个答案引起了我的关注。 build machine上有多个.NET framework,会不会很麻烦?
MSBuild
优点:
- 商业支持
- 社区在发展
- 与 VS 和 TFS 集成
- 与 .Net 保持同步
缺点:
- 重写当前脚本
- 不为人所熟知
南特
优点:
- 已经在使用
- 为人所熟知
缺点:
- 很久没更新了(自2012年)
- 社区不活跃
- 缺少新的 .Net 支持
有一个 属性 nant.settings.currentframework
用于设置目标框架,以防您有多个 .net 框架
<property name="nant.settings.currentframework" value="net-2.0" />
- 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# 工作室。