2017-04-07 165 views
19

这个问题与Setting the version number for .NET Core projects非常相似,但不一样。在撰写本文(1.1)和VS2017时使用最新的.NET Core稳定版本时,.NET Core已从基于JSON的项目文件切换到CSPROJ文件。设置.NET Core项目的版本号 - CSPROJ - 不是JSON项目

所以 - 我想要做的是建立一个CI环境,我希望能够修改之前的一个构建使用正确的版本号标记我的版本。

如果我这样使用老(SharedAssemblyInfo.cs招)的属性:

[assembly: AssemblyFileVersion("3.3.3.3")] 
[assembly: AssemblyVersion("4.4.4.4")] 

在项目的某个地方,我得到
CS0579 - Duplicate 'System.Reflection.AssemblyFileVersionAttribute'

CS0579 - Duplicate 'System.Reflection.AssemblyVersionAttribute'
错误时建设。

当挖掘到这一点,我发现有一个文件,它看起来像这样在\obj\Debug\netcoreapp1.1在构建过程中(我之前建立它不存在)产生:

//------------------------------------------------------------------------------ 
// <auto-generated> 
//  This code was generated by a tool. 
//  Runtime Version:4.0.30319.42000 
// 
//  Changes to this file may cause incorrect behavior and will be lost if 
//  the code is regenerated. 
// </auto-generated> 
//------------------------------------------------------------------------------ 

using System; 
using System.Reflection; 

[assembly: System.Reflection.AssemblyCompanyAttribute("TestApplication")] 
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] 
[assembly: System.Reflection.AssemblyDescriptionAttribute("Package Description")] 
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.1.99.0")] 
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.1.99")] 
[assembly: System.Reflection.AssemblyProductAttribute("TestApplication")] 
[assembly: System.Reflection.AssemblyTitleAttribute("TestApplication")] 
[assembly: System.Reflection.AssemblyVersionAttribute("1.1.99.0")] 

// Generated by the MSBuild WriteCodeFragment class. 

问题 - 我该如何做这一点?
所以我可以看到这必须以某种方式从项目属性“包页面”中输入的值生成,但我不知道在CI机器上更改这些值的正确方法是什么。

理想情况下,我希望能够在我的(詹金斯)CI脚本中指定所有这些信息,但我只能设置版本号。

编辑 - 更多信息
读取第一个答案之后,我想弄清楚,我既创造服务的NuGet包 - 我宁愿版本的一切的1路,这将是像旧的JSON项目,我可以只更新一个文件。

UPDATE 我的脚本更改了的csproj文件,这在我看来是相当哈克,因为我需要修改看起来像这样的节会...

<PropertyGroup> 
<OutputType>Exe</OutputType> 
<TargetFramework>netcoreapp1.1</TargetFramework> 
<Version>1.0.7777.0</Version> 
<AssemblyVersion>1.0.8888.0</AssemblyVersion> 
<FileVersion>1.0.9999.0</FileVersion> 
<Company>MyCompany</Company> 
<Authors>AuthorName</Authors> 
<Product>ProductName</Product> 
<Description /> 
<Copyright>Copyright © 2017</Copyright> 
</PropertyGroup> 

所以 - 问题这里有多个'PropertyGroup'元素;其他人似乎被贴上标签 - 但不知道CSPROJ是如何放在一起的,我不能说这总是如此。

我工作的前提是包的细节将始终填充,否则值标记(上面)不会出现在XML中 - 所以然后我可以使用脚本来更新值。如果值标签不存在,我不清楚哪个PropertyGroup元素插入值(以及哪个顺序,因为这看起来很重要;更改顺序使我无法在VS2017中加载项目)。

我仍然抱着比这更好的解决方案!

更新:有人将这个问题标记为可能的副本(Auto Versioning in Visual Studio 2017 (.NET Core)) - 之前我没有看到过这个问题,现在看来它似乎几乎相同,只是我不想设置版本号。此外,这个问题的答案不能解决我的问题 - 只会问我在问题中提出的问题。对我的问题的接受答案正是我需要解决我的问题的答案 - 所以当另一个问题首先出现并且看起来相同时 - 它根本没有帮助我。也许一个国防部可以帮助?

+0

[自动版本控制在Visual Studio 2017(.NET Core)]中可能出现重复(http://stackoverflow.com/questions/43019832/auto-versioning-in- visual-studio-2017-net-core) – Tagc

+0

包含解释的更新答案 - 我没有看到该帖子;它似乎是相同的,但它不回答我的问题。这篇文章的接受答案完美地回答了我的问题。 – Jay

回答

24

你可以通过/p:PropertyName=Value作为参数传递给dotnet restoredotnet builddotnet pack覆盖命令行中的任何财产。

目前,版本组成工作原理是: 如果Version没有设置,使用VersionPrefix(默认为1.0.0,如果取消设置)和 - 如果存在的话 - 追加VersionSuffix

所有其他版本默认为Version

因此,例如,你可以在你的csproj设置<VersionPrefix>1.2.3</VersionPrefix>,然后调用dotnet pack --version-suffix beta1产生YourApp.1.2.3-beta1.nupkg(如果你有你想要的版本,后缀将应用于以及项目的参考,你需要在这之前调用dotnet restore /p:VersionSuffix=beta1 - 这是工具中已知的错误)。

当然,您也可以使用自定义变量,有关几个示例,请参阅this GitHub issue

有关受支持的程序集属性的完整参考,我建议查看构建逻辑的源代码here(用$()包围的值是使用的属性)。 由于我已经在谈论源代码,this是组成版本和其他一些属性的逻辑。

+0

'/ p:'参数可能是我正在寻找;我正在阅读的内容是.NET Core 1.1的新版本,它将参数直接传递给dotnet msbuild(也是.NET Core 1.1中的新增功能)。我将不得不在周末玩这个游戏,看看它是否给了我期望的结果,但看起来很有希望。 – Jay

+0

刚刚试过这个,并且它是传递给'dotnet msbuild'命令的'/ p:'参数,它为我完成了这个技巧。谢谢! – Jay

3

我用詹金斯+八达通CI,并按照相当奏效:

  1. 有一个预先构建Powershell脚本,可以采取建立CI号作为PARAM或默认的东西预设。
  2. CI的项目中有一个单独的nuspec文件。
  3. 预生成脚本将使用最新的内部版本更新nuspec文件。
  4. 与Jenkins发布项目。
  5. 使用#2的nuspec文件手动拨打电话Nuget
  6. nuget包推到八达通。
+0

nuspec文件是否适用于软件包?我没有计划打包所有东西 - 我正在创建一系列业务微服务,这些服务最终将在Linux环境中执行(可能位于码头集装箱中)。无论如何,如果nuspec只是标记NuGet包,那么这不是我所追求的(虽然它很有用)。 – Jay

+0

是的,不幸的是只有包... – Ignas

+2

没问题,你仍然教我一些东西,因此upvote :) – Jay

5

要直接回答您的问题:msbuild的新SDK将自动生成程序集信息文件。您可以使用msbuild指令来抑制该指令(通过示例查看它:在基于project.json的项目上调用dotnet migrate)。

但让我告诉你我的处理:我有多个项目共享相同的版本。我添加了一个version.props文件,其中包含一个属性组,其中包含一个名为VersionPrefix的项目。我通过csproj文件包含这个文件(Include声明)。我还删除了所有AssemblyInfo.cs文件,并让SDK为我生成它们。

我在构建期间修改version.props文件。

+3

如果您在目录层次结构中创建一个名为'Directory.build.props'的文件,它将自动导入,并且您不需要''指令。 –

+0

太棒了。谢谢。 – Thomas

+2

+1:它也是一个有用的答案,但是我已经用@ MartinUllrich的答案去了,因为构建命令行比修改文件更容易,因为我在最小的Linux中完成了这一切环境。 – Jay

0

正如我回答here,我做了一个名为dotnet-setversion的CLI工具,您可以使用它来版本化* .csproj样式的.NET Core项目。

在构建CI期间,可以使用GitVersion或其他工具来确定项目的版本号,然后在项目根目录中调用dotnet-setversion $YOUR_VERSION_STRING

+0

它非常聪明,但我可能不理解为什么你会使用这个,只要将'/ p:'参数传递给'dotnet msbuild'就可以完成这个问题的接受答案中所建议的工作?看看源代码,这看起来像只更新'Version'元素。 – Jay

+0

@Jay我甚至不知道它存在。 “/ p”标志在1.1.0中似乎是新的。如果你运行'dotnet --help',它甚至不会提到这个标志。我已经提出了接受的答案。 – Tagc

+0

此外,它只更新'版本'元素,因为这是所有必需的(你也可以包含后缀信息)。如果您设置了'Version',则不需要设置'VersionSuffix'或'VersionPrefix'。 – Tagc

1

如果您在项目文件中丢失了它们,MsBuild 2017会生成一些程序集信息。

如果你可以看到你可以看看的MSBuild目标文件:

[VS Install Dir] \MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.GenerateAssemblyInfo.targets

你会看到在你的项目文件中禁用生成的程序集信息,以防止你的生成工具复制你可以使用一些属性。

  • <GenerateAssemblyInfo>(该属性将开/关所有生成组件信息)
  • <GenerateAssemblyCompanyAttribute>
  • <GenerateAssemblyConfigurationAttribute>
  • <GenerateAssemblyCopyrightAttribute>
  • <GenerateAssemblyDescriptionAttribute>
  • <GenerateAssemblyFileVersionAttribute>
  • <GenerateAssemblyInformationalVersionAttribute>
  • <GenerateAssemblyProductAttribute>
  • <GenerateAssemblyTitleAttribute>
  • ​​3210
  • <GenerateNeutralResourcesLanguageAttribute>
5
dotnet build /p:AssemblyVersion=1.2.3.4 

为你做这项工作?

+0

它的确如此,但这个答案与这个问题的接受答案有什么不同或添加了什么(这是4个月前发布的)? – Jay

+1

它更简洁 - 但上面的答案没有提到完全设置AsemblyVersion属性。它继续关于VersionPrefix和VersionSuffix以及编辑csproj文件等,提到您可以从命令行设置所需的任何属性,但不会提供用于完成请求结果的实际命令行。我碰巧遇到了这个问题,寻找我最终找到的答案 - 但没有在这里找到答案。 –

+0

对不起,我不能满足这一点,它完全涵盖了马丁的答案,它指示我检查msbuild命令行参考\源代码,如果你读我的问题,(最终更新),我不只是试图设置版本号。也许你的帖子会帮助别人。 – Jay