设置.NET Core项目的版本号 - CSPROJ - 而不是JSON项目

时间:2017-04-07 09:13:54

标签: asp.net-core continuous-integration .net-core versioning

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

所以 - 我要做的是设置一个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.

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

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

编辑 - 更多信息
在阅读完第一个答案之后,我想明确表示我正在创建服务和NuGET包 - 我宁愿有一种方法对所有内容进行版本控制,这就像旧的JSON项目,我只能更新单个文件。

更新 我正在编写对CSPROJ文件的更改脚本,在我看来这是一个相当hacky,因为我需要修改的部分看起来像这样......

<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>

所以 - 这里的问题是有多个&#39; PropertyGroup&#39;要素;其他人似乎被标记了 - 但不知道CSPROJ是如何组合在一起的,我不能说这种情况总是如此。

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

我仍然坚持要比这个更好的解决方案!

更新:在有人将此问题标记为可能重复(Auto Versioning in Visual Studio 2017 (.NET Core))之后 - 我之前没有看过这个问题,现在阅读它似乎几乎相同,除了我不想只是设置版本号。此外,这个问题的答案并没有解决我的问题 - 只询问我在问题中提出的问题。接受我的问题的答案正是我需要解决问题的答案 - 所以当另一个问题首先出现并且显得相同时 - 它根本没有帮助我。也许mod可以帮忙吗?

9 个答案:

答案 0 :(得分:47)

您可以通过将/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是组成版本和其他一些属性的逻辑。

答案 1 :(得分:27)

dotnet build /p:AssemblyVersion=1.2.3.4

这对你有用吗?

答案 2 :(得分:9)

对于那些寻求采用其他自动(CI)方法执行此操作的用户,请考虑根据环境变量在.csproj文件中使用条件。例如,您通常可能具有硬编码的版本前缀和基于时间戳的后缀。但是对于适当的发行版,您希望将其替换为在CI构建期间设置的单个版本。为此,您可以在调用dotnet build之前设置环境变量:假设RELEASE_VERSION

在.csproj文件的<PropertyGroup>下,您将具有以下内容:

<Version Condition="'$(RELEASE_VERSION)' != ''">$(RELEASE_VERSION)</Version>
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.1</VersionPrefix>
<VersionSuffix Condition="'$(RELEASE_VERSION)' == ''">$([System.DateTime]::UtcNow.ToString(`yyyyMMdd-HHmm`))</VersionSuffix>

以上条件被设置为,如果环境变量RELEASE_VERSION为空,则使用常规前缀和后缀标记。但是,如果不为空,则使用签名版本标记。

答案 3 :(得分:7)

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

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

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

答案 4 :(得分:3)

我使用Jenkins + Octopus进行CI,并且效果非常好:

  1. 有一个预构建[WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}TransportBinding registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}TransportToken registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}HttpsToken registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}AlgorithmSuite registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Basic256 registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Layout registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}Lax registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}IncludeTimestamp registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}SignedSupportingTokens registered. [WARNING ] No assertion builder for type {http://schemas.xmlsoap.org/ws/2005/07/securitypolicy}UsernameToken registered. [ERROR ] None of the policy alternatives can be satisfied. None of the policy alternatives can be satisfied. 脚本,可以将CI版本号作为参数或默认设置为预设。
  2. 在CI的项目中有一个单独的Powershell文件。
  3. 预构建脚本将使用最新的构建版本更新nuspec文件。
  4. 使用Jenkins发布项目。
  5. 使用来自#2的nuspec文件手动呼叫Nuget
  6. nuspec包推送到八达通。

答案 5 :(得分:3)

如果您在项目文件中遗漏了它们,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>
  • <GenerateAssemblyVersionAttribute>
  • <GenerateNeutralResourcesLanguageAttribute>

答案 6 :(得分:1)

正如我已回答here,我已经创建了一个名为dotnet-setversion的CLI工具,您可以将其用于版本化* .csproj样式的.NET Core项目。

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

答案 7 :(得分:0)

传递/ p:PropertyName = Value作为参数对我不起作用(ASP.Net Core 2.0 Web App)。 我在市场空间找到了Manifest Versioning Build Tasks:https://marketplace.visualstudio.com/items?itemName=richardfennellBM.BM-VSTS-Versioning-Task

答案 8 :(得分:0)

我在.csproj中做什么

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <Deterministic>false</Deterministic>
    <AssemblyVersion>2.0.*</AssemblyVersion>
  </PropertyGroup>
</Project>

在AssemblyVersion中指定通配符,然后打开确定性标志。将为通配符添加数字。