如何使用 OctoPack 以 NuGet 包的名称获取 MSBuild 内部版本号?

How to get MSBuild build number in name of NuGet package using OctoPack?

我正在试用 Octopus Deploy (3.4.12) 并希望自动使用 MS Build 名称中的内部版本号作为我的 NuGet 程序包名称。例如,如果我最新的 MSBuild drop 名称是 'MyApp Build_20161019.2' 并且我的应用程序名称是 MyApp,那么我希望我的包被称为MyApp.20161019.2.0.nupkg

原因是应用程序的程序集版本没有改变(历史原因,非否定),所以除非我每次都手动将内部版本号作为构建参数传递给 OctoPack(这会让人眼前一亮)自动打包 IMO), 我无法将包加载到 Octopus 库中。

我正在使用老式的 TFS XAML 顺便说一下构建定义。

我应该指出,我找到了一个博客,上面说要创建自定义构建模板并更改 运行 MSBuild 项目,以便参数为

String.Format("/p:SkipInvalidConfigurations=true {0} /p:OctoPackPackageVersion={1}", AdvancedBuildSettings.GetValue(Of String)("MSBuildArguments", String.Empty), BuildDetail.BuildNumber.Split(CChar("_"))(1))

并按照步骤操作,但构建失败并出现以下错误:

Validation Error: The private implementation of activity '1: DynamicActivity' has the following validation error: Compiler error(s) encountered processing expression "String.Format("/p:SkipInvalidConfigurations=true {0} /p:OctoPackPackageVersion={1}", AdvancedBuildSettings.GetValue(Of String)("MSBuildArguments", String.Empty), BuildDetail.BuildNumber.Split(CChar("_"))(1))". 'Microsoft.TeamFoundation.Build.Client.BuildDetail' is not accessible in this context because it is 'Friend'.

好的,我在与 Git 构建相关的类似问题的帮助下找到了如何做到这一点:

WARNING!! AFAIK you're going to need VS2013 for this. You can't do it in VS2015.

为了完整起见,我列出了我必须跳跃的所有flaming hoops步骤。

第一次尝试:

我尝试通过提供以下 MSBuild 参数 TF_BUILD 环境变量 TF_BUILD_BUILDNUMBER 简单地设置 OctoPack 包号

/p:RunOctoPack=true /p:OctoPackPackageVersion=”$(TF_BUILD_BUILDNUMBER)”

但是 TF_BUILD_BUILDNUMBER 包括文本(我认为是应用程序的名称)以及数字,例如CIBuild_20130613.6 导致 NuGet 错误,因为 NuGet 只能处理数字。另外我真的只想要 20130613.6 部分。

第二次尝试:

研究表明我必须创建一个定制的构建过程模板。作为起点,我通过编辑现有的构建过程定义(使用默认模板)并单击下载 link.

下载默认模板的副本

接下来我将模板重命名为 OctoPackBuild.xaml 并将其添加到 TFS 中。我把它放在一个名为 BuildProcessTemplates 的文件夹中,与我要构建的项目分开,因为这个模板可以用于任何项目。

从技术上讲,您应该创建一个工作流 Activity 库项目并将模板添加到项目中,然后将项目签入 TFS,但我发现这是不必要的。如果您想全面了解,请参阅 msdn article

xaml 文件在 TFS 中后,您需要在 Visual Studio 中编辑它以获取对内部版本号的引用。以下步骤来自对 this msdn question.

的回答

a) 查看 OctoPackBuild.xaml 文件并在 Visual Studio 2013 中打开它。

b) 单击 xaml 编辑器底部的导入选项卡,并添加对 Microsoft.TeamFoundation.Build.Activities.Extensions.

的引用

c) 在 xaml 编辑器中单击“Overall build process”容器,然后单击“变量”选项卡底部。添加一个名为 BuildDetail 的变量,并将其类型设置为 IBuildDetail

d) 从工具箱中,将 GetEnvironmentVariable activity 拖到 Update Build Number [=141= 之后],并将类型设置为 IBuildDetail。编辑 activity 属性;将名称 属性 设置为 WellKnownEnvironmentVariables.BuildDetail,将显示名称设置为 'Get Build Details'(或任何让你的船漂浮的东西),结果为 BuildDetail <- 这个是您创建的变量的名称。

e) 现在您可以访问 BuildDetail 对象,您可以将 BuildNumber 属性 传递给 MSBuild。为此,请编辑 'Run MSBuild' activity 的 CommandLineArguments 属性 并将值设置为

String.Format("/p:SkipInvalidConfigurations=true {0} /p:OctoPackPackageVersion={1}", AdvancedBuildSettings.GetValue(Of String)("MSBuildArguments", String.Empty), BuildDetail.BuildNumber.Split(CChar("_"))(1))

您应该注意 BuildDetail 现在指的是您的变量,而不是 'Microsoft.TeamFoundation.Build.Client.BuildDetail'。

此外,重要的是要了解 BuildNumber 的格式为 [text]_[numbers]。所以 Split 函数正在删除文本部分,只将数字传递给 OctoPack。如果您不拆分 BuildNumber,则会导致我在第一次尝试中提到的 NuGet 问题。这也意味着,如果您在构建名称中添加额外的下划线,那么您将必须 select 元素 #2,而不是 #1。

f) 将您的自定义构建模板 (OctoPackBuild.xaml) 重新检查到 TFS 中。

g) 接下来,您需要编辑构建过程以使用自定义模板而不是默认模板。

您不能在本练习中使用 VS2015 的原因是 UI 不允许您从 TFS select xaml 文件。看起来 MS 运行 超出了预算,UI 的那部分被破坏了。

VS2010 也不起作用,因为它不能与 TFS 2013 模板一起使用。

我让它工作的唯一方法是使用 VS2013 并从那里编辑构建过程。 VS2013 将允许您指定新模板并在 TFS 中导航以查找您的 OctoPackBuild.xaml 文件。

h) 然后,您在构建过程中所要做的就是将 /p:RunOctoPack=true 添加到 MSBuild 参数中,您就完成了。

希望这对某人有所帮助!