为 .NET Core 项目设置版本号 - CSPROJ - 而不是 JSON 个项目
Setting the version number for .NET Core projects - CSPROJ - not JSON projects
这个问题和Setting the version number for .NET Core projects很相似,但又不一样。在撰写本文时使用最新稳定版本的 .NET Core (1.1) 和 VS2017,.NET Core 已从基于 JSON 的项目文件切换到 CSPROJ 文件。
所以 - 我想要做的是建立一个 CI 环境,我希望能够在其中 modify something用正确的版本号标记我的构建的构建。
如果我使用旧的(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.
问题 - 我该怎么做?
所以我可以看到这必须以某种方式从项目属性 'package page' 中输入的值生成,但我不知道在我的 CI 机器上更改这些值的正确方法是什么。
理想情况下,我希望能够在我的 (Jenkins) CI 脚本中指定所有这些信息,但我只满足于设置版本号。
编辑 - 更多信息
阅读第一个答案后,我想明确表示我正在创建服务和 NuGET 包 - 我更愿意使用一种方式对所有内容进行版本控制,就像旧的 JSON 项目一样,我可以只更新单个文件。
更新
我正在编写对 CSPROJ 文件的更改脚本,在我看来这相当老套,因为我需要 modify 的部分看起来像这样...
<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 中加载项目)。
我仍在等待比这个更好的解决方案!
更新:在有人将这个问题标记为可能重复后 () - 我以前没有看到这个问题,现在阅读它似乎几乎相同,只是我不想设置版本号。另外,这个问题的答案并不能解决我的问题——只问我在问题中问的问题。我的问题的可接受答案正是我解决问题所需的答案 - 所以虽然另一个问题排在第一位并且看起来相同 - 但它根本没有帮助我。也许 mod 可以提供帮助?
我将 Jenkins + Octopus 用于 CI,以下工作得很好:
- 有一个预构建
Powershell
脚本,可以将 CI 构建号作为参数或默认为预设值。
- 在 CI 的项目中有一个单独的
nuspec
文件。
- 预构建脚本会使用最新的构建版本更新
nuspec
文件。
- 使用 Jenkins 发布项目。
- 使用来自 #2 的
nuspec
文件手动调用 Nuget
。
- 将
nuget
包推送到八达通。
您可以从命令行覆盖任何 属性,方法是将 /p:PropertyName=Value
作为参数传递给 dotnet restore
、dotnet build
和 dotnet 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 是构成版本和其他一些属性的逻辑。
直接回答您的问题:适用于 msbuild 的新 SDK 会自动生成程序集信息文件。您可以使用 msbuild 指令抑制它(通过示例查看它:在基于 project.json 的项目上调用 dotnet migrate
)。
但是让我告诉你我的处理方式:我有多个项目共享同一个版本。我添加了一个 version.props
文件,其中包含一个 属性 组,其中包含一个名为 VersionPrefix
的项目。我通过 csproj 文件(Include
语句)包含了这个文件。我还删除了所有 AssemblyInfo.cs
文件并让 SDK 为我生成它们。
我在构建过程中修改了 version.props
文件。
正如我回答的那样 , I've made a CLI tool called dotnet-setversion 您可以使用它来对 *.csproj 风格的 .NET Core 项目进行版本控制。
在 CI 构建期间,您可以使用 GitVersion 或其他工具来确定项目的版本号,然后在项目根目录中调用 dotnet-setversion $YOUR_VERSION_STRING
。
如果您在项目文件中缺少它们,MsBuild 2017 将生成一些程序集信息。
如果你能阅读 msbuild 目标文件,你可以看看:
[VS Install Dir] \MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.GenerateAssemblyInfo.targets
您会看到您可以在项目文件中使用一些 属性 来禁用生成的程序集信息,以防止与您生成的工具重复。
<GenerateAssemblyInfo>
(这个属性会on/off全部生成汇编信息)
<GenerateAssemblyCompanyAttribute>
<GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCopyrightAttribute>
<GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyProductAttribute>
<GenerateAssemblyTitleAttribute>
<GenerateAssemblyVersionAttribute>
<GenerateNeutralResourcesLanguageAttribute>
dotnet build /p:AssemblyVersion=1.2.3.4
这对你有用吗?
传递 /p:PropertyName=Value 作为参数对我不起作用(ASP.Net Core 2.0 Web App)。
我在市场上找到了清单版本控制构建任务:https://marketplace.visualstudio.com/items?itemName=richardfennellBM.BM-VSTS-Versioning-Task
在我的例子中,主键是 /property:Version=1.2.3.4
。以下命令行完成了这项工作:
dotnet build SolutionName.sln -c Release /property:Version=1.2.3.4
这将覆盖程序集默认版本。
更新
所以另外只是为了在软件发布的实际用例中澄清这一点。
例如,当您发布软件时,您可以设置文件版本和产品版本,如前所述here。
举个例子:
dotnet publish .\ProjectFolder\Project.csproj -r win-x64 /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true --self-contained true -o ReleaseFolderName -c Release /p:AssemblyVersion=1.2.3.4 /p:Version=1.2.3.4-product-version
将发布软件,右击软件点击详细信息,会出现如下图:
我在 .csproj 中做的就是这个
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<Deterministic>false</Deterministic>
<AssemblyVersion>2.0.*</AssemblyVersion>
</PropertyGroup>
</Project>
在 AssemblyVersion 中指定通配符,然后关闭 Deterministic 标志。将为通配符添加数字。
对于那些正在寻找不同的自动化 (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
为空,则使用正常的前缀和后缀标签。但如果它不为空,则使用 signular 版本标签。
这个问题和Setting the version number for .NET Core projects很相似,但又不一样。在撰写本文时使用最新稳定版本的 .NET Core (1.1) 和 VS2017,.NET Core 已从基于 JSON 的项目文件切换到 CSPROJ 文件。
所以 - 我想要做的是建立一个 CI 环境,我希望能够在其中 modify something用正确的版本号标记我的构建的构建。
如果我使用旧的(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.
问题 - 我该怎么做?
所以我可以看到这必须以某种方式从项目属性 'package page' 中输入的值生成,但我不知道在我的 CI 机器上更改这些值的正确方法是什么。
理想情况下,我希望能够在我的 (Jenkins) CI 脚本中指定所有这些信息,但我只满足于设置版本号。
编辑 - 更多信息
阅读第一个答案后,我想明确表示我正在创建服务和 NuGET 包 - 我更愿意使用一种方式对所有内容进行版本控制,就像旧的 JSON 项目一样,我可以只更新单个文件。
更新 我正在编写对 CSPROJ 文件的更改脚本,在我看来这相当老套,因为我需要 modify 的部分看起来像这样...
<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 中加载项目)。
我仍在等待比这个更好的解决方案!
更新:在有人将这个问题标记为可能重复后 (
我将 Jenkins + Octopus 用于 CI,以下工作得很好:
- 有一个预构建
Powershell
脚本,可以将 CI 构建号作为参数或默认为预设值。 - 在 CI 的项目中有一个单独的
nuspec
文件。 - 预构建脚本会使用最新的构建版本更新
nuspec
文件。 - 使用 Jenkins 发布项目。
- 使用来自 #2 的
nuspec
文件手动调用Nuget
。 - 将
nuget
包推送到八达通。
您可以从命令行覆盖任何 属性,方法是将 /p:PropertyName=Value
作为参数传递给 dotnet restore
、dotnet build
和 dotnet 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 是构成版本和其他一些属性的逻辑。
直接回答您的问题:适用于 msbuild 的新 SDK 会自动生成程序集信息文件。您可以使用 msbuild 指令抑制它(通过示例查看它:在基于 project.json 的项目上调用 dotnet migrate
)。
但是让我告诉你我的处理方式:我有多个项目共享同一个版本。我添加了一个 version.props
文件,其中包含一个 属性 组,其中包含一个名为 VersionPrefix
的项目。我通过 csproj 文件(Include
语句)包含了这个文件。我还删除了所有 AssemblyInfo.cs
文件并让 SDK 为我生成它们。
我在构建过程中修改了 version.props
文件。
正如我回答的那样
在 CI 构建期间,您可以使用 GitVersion 或其他工具来确定项目的版本号,然后在项目根目录中调用 dotnet-setversion $YOUR_VERSION_STRING
。
如果您在项目文件中缺少它们,MsBuild 2017 将生成一些程序集信息。
如果你能阅读 msbuild 目标文件,你可以看看:
[VS Install Dir] \MSBuild\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.GenerateAssemblyInfo.targets
您会看到您可以在项目文件中使用一些 属性 来禁用生成的程序集信息,以防止与您生成的工具重复。
<GenerateAssemblyInfo>
(这个属性会on/off全部生成汇编信息)<GenerateAssemblyCompanyAttribute>
<GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCopyrightAttribute>
<GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyProductAttribute>
<GenerateAssemblyTitleAttribute>
<GenerateAssemblyVersionAttribute>
<GenerateNeutralResourcesLanguageAttribute>
dotnet build /p:AssemblyVersion=1.2.3.4
这对你有用吗?
传递 /p:PropertyName=Value 作为参数对我不起作用(ASP.Net Core 2.0 Web App)。 我在市场上找到了清单版本控制构建任务:https://marketplace.visualstudio.com/items?itemName=richardfennellBM.BM-VSTS-Versioning-Task
在我的例子中,主键是 /property:Version=1.2.3.4
。以下命令行完成了这项工作:
dotnet build SolutionName.sln -c Release /property:Version=1.2.3.4
这将覆盖程序集默认版本。
更新
所以另外只是为了在软件发布的实际用例中澄清这一点。
例如,当您发布软件时,您可以设置文件版本和产品版本,如前所述here。
举个例子:
dotnet publish .\ProjectFolder\Project.csproj -r win-x64 /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true --self-contained true -o ReleaseFolderName -c Release /p:AssemblyVersion=1.2.3.4 /p:Version=1.2.3.4-product-version
将发布软件,右击软件点击详细信息,会出现如下图:
我在 .csproj 中做的就是这个
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<Deterministic>false</Deterministic>
<AssemblyVersion>2.0.*</AssemblyVersion>
</PropertyGroup>
</Project>
在 AssemblyVersion 中指定通配符,然后关闭 Deterministic 标志。将为通配符添加数字。
对于那些正在寻找不同的自动化 (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
为空,则使用正常的前缀和后缀标签。但如果它不为空,则使用 signular 版本标签。