Visual Studio 2017(.NET Core)中的自动版本控制


112

我花了大部分时间尝试在.NETCoreApp 1.1(Visual Studio 2017)中找到一种自动递增版本的方法。

我知道AssemblyInfo.cs是在文件夹中动态创建的: obj/Debug/netcoreapp1.1/

它不接受以下旧方法: [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

如果将项目设置为可打包,则可以在其中设置版本,但这似乎用于构建AssemblyInfo.cs文件。

我的问题是,有没有人想出如何控制.NET Core(或相应的.NETStandard)项目中的版本。


我不知道您对此有多远,但似乎我以不同的方式问了几乎相同的问题(stackoverflow.com/a/43280282/685341)-也许对此问题的公认答案会有所帮助;您只需在构建脚本中将/p:标志传递到dotnet msbuild,然后设置版本,公司,版权...所有这些好东西。
杰伊

2
谢谢(你的)信息。那只是打开了其他选项。
Jason H

以前* AssemblyVersion支持*,AssemblyFileVersion不支持-请参阅使用Visual Studio时可以自动增加文件生成版本吗?
Michael Freidgeim's

4
FWIW不支持汇编版本中的通配符,因为对于这些新项目,编译器的“确定性”模式默认情况下处于活动状态。由于自动增量会破坏确定性(相同的输入>相同的输出),因此在该模式下是不允许的。您可以<Deterministic>False</Deterministic>在csproj中进行设置以使用它。(或使用任何其他MSbuild逻辑来计算<VersionPrefix>/ <Version>
Martin Ullrich

Answers:


23

我一直在使用csproj配置格式为VS2017中的Net Core应用程序寻找版本增量器。

我找到了一个名为dotnetump的项目,该项目适用于project.json格式,但很难找到.csproj格式的解决方案。编写者实际上是.netprob提出了.csproj格式的解决方案,它称为MSBump。

GitHub上有一个针对该项目的项目:

https://github.com/BalassaMarton/MSBump

您也可以在此查看代码及其在Nuget上可用的代码。只需在Nuget上搜索MSBump。


1
我建议使用最新的2.1.0版本的MSBump,它更好地支持切换配置,并且还设置当前版本的版本,而不是下一个版本(如先前的版本)。
顿·巴拉萨

我看到它现在还支持MSBuild,而之前需要Visual Studio。
ravetroll '17

2
是的,它还支持多目标项目。
顿·巴拉萨

4
考虑使用GitVersioning。它可能适合在您的CI环境中运行。github.com/AArnott/Nerdbank.GitVersioning
Henrique

1
即使您未进行任何更改,MSBump也会在每个版本上增加版本,这从长期来看会导致很多问题。有时版本不同步,而一个版本落后于另一个。
康拉德(Konrad)

68

<Deterministic>False</Deterministic><PropertyGroup>.csproj 的一部分内添加 

使AssemblyVersion *工作的解决方法在“ .Net Core#22660上[AssemblyVersion]中的通配符错误消息中描述

仅当构建不确定时才允许使用通配符,这是.Net Core项目的默认设置。添加  <Deterministic>False</Deterministic> 到csproj可以解决此问题。

.Net Core开发人员认为确定性构建有益的原因已在http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html中描述, 而编译器应具有确定性:相同的输入生成相同的输出# 372

但是,如果您使用的是TeamCity,TFS或其他CI / CD工具,则最好由它们控制和递增版本号,然后将其作为参数传递(如其他答案中所建议),例如

msbuild /t:build /p:Version=YourVersionNumber /p:AssemblyVersion=YourVersionNumber

NuGet软件包的软件包编号

msbuild /t:pack /p:Version=YourVersionNumber   

谢谢!我知道有一个隐藏的杠杆可以打开宝藏室!我正在将一个旧项目迁移到新的.NET SDK,我真的想快速地做到这一点,而不必麻烦地寻找自动版本增加解决方案。实际上,与旧方法的兼容性越好,我的案例越好。
Ivaylo Slavov '18

这是IMO的最佳答案。它允许构建工具正常工作。至少我现在可以使用外部机制将数字输入构建中。
Michael Yanni

请再扩大一点答案:建议的添加内容应放入.csproj的<PropertyGroup>部分。并感谢您提供的出色答案,当然!
GerardV '18年

1
@gerardv,完成了,但是您可以自己改善编辑stackoverflow.com/help/editing
Michael Freidgeim

61

如果您使用Visual Studio Team Services / TFS或某些其他CI构建过程来内置版本控制,则可以利用msbuild的Condition属性,例如:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">0.0.1-local</Version>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(BUILD_BUILDNUMBER)</Version>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
  </ItemGroup>

</Project>

这将告诉.NET Core编译器使用BUILD_BUILDNUMBER环境变量(如果存在)中的任何内容,或者回退到0.0.1-local如果要在本地计算机上进行构建的情况。


很好,我喜欢这种方法,因为环境变量只能在构建服务器上设置,而这些条件决定了二进制文件中的程序集。
jbooker

似乎无法在TFS 2010上使用,但希望我们能尽快实现这一目标!
Mark Adamson

这不是一个不错的解决方案,但是如果该解决方案有很多项目,可能会有些麻烦。
tofutim

好的解决方案。我确实得到了Build异常。我不得不稍微更改配置以修复它。stackoverflow.com/a/59858009/106227
Stu Harper

NET Core 2.1.2和TFS2017U3一起使用时效果很好
Dave Johnson

15

我想出了与星号(*)- AssemblyVersion(“ 1.0。 ”)*的旧AssemblyVersion属性几乎相同的解决方案

的AssemblyVersion的AssemblyFileVersion是MSBuild项目.csproj的文件(而不是在AssemblyInfo.cs中)财产文件版本(生成AssemblyFileVersionAttribute)和的AssemblyVersion(产生AssemblyVersionAttribute)。在MSBuild过程中,我们使用自定义的MSBuild任务生成版本号,然后覆盖这些FileVersionAssemblyVersion的使用任务中的新值属性的值。

因此,首先我们创建自定义MSBuild任务GetCurrentBuildVersion

public class GetCurrentBuildVersion : Task
{
    [Output]
    public string Version { get; set; }
 
    public string BaseVersion { get; set; }
 
    public override bool Execute()
    {
        var originalVersion = System.Version.Parse(this.BaseVersion ?? "1.0.0");
 
        this.Version = GetCurrentBuildVersionString(originalVersion);
 
        return true;
    }
 
    private static string GetCurrentBuildVersionString(Version baseVersion)
    {
        DateTime d = DateTime.Now;
        return new Version(baseVersion.Major, baseVersion.Minor,
            (DateTime.Today - new DateTime(2000, 1, 1)).Days,
            ((int)new TimeSpan(d.Hour, d.Minute, d.Second).TotalSeconds) / 2).ToString();
    }
}

从Task类继承Microsoft.Build.Utilities.Task从类Microsoft.Build.Utilities.Core NuGet包的。它在输入上带有BaseVersion属性(可选),并在Version输出属性中返回生成的版本。获取版本号的逻辑与.NET自动版本控制相同(内部版本号是自2000年1月1日以来的天数,而修订是自午夜以来的半秒)。

为了构建此MSBuild任务,我们将.NET Standard 1.3类库项目类型与此类一起使用。

.csproj文件如下所示:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard1.3</TargetFramework>
    <AssemblyName>DC.Build.Tasks</AssemblyName>
    <RootNamespace>DC.Build.Tasks</RootNamespace>
    <PackageId>DC.Build.Tasks</PackageId>
    <AssemblyTitle>DC.Build.Tasks</AssemblyTitle>
  </PropertyGroup>
 
  <ItemGroup>
    <PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012" />
    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012" />
  </ItemGroup>
</Project>

这个任务项目也可以在我的GitHub holajan / DC.Build.Tasks中找到。

现在,我们将MSBuild设置为使用此任务,并设置FileVersionAssemblyVersion属性。在.csproj文件中,它看起来像这样:

<Project Sdk="Microsoft.NET.Sdk">
  <UsingTask TaskName="GetCurrentBuildVersion" AssemblyFile="$(MSBuildThisFileFullPath)\..\..\DC.Build.Tasks.dll" />
 
  <PropertyGroup>
    ...
    <AssemblyVersion>1.0.0.0</AssemblyVersion>
    <FileVersion>1.0.0.0</FileVersion>
  </PropertyGroup>
 
  ...
 
  <Target Name="BeforeBuildActionsProject1" BeforeTargets="BeforeBuild">
    <GetCurrentBuildVersion BaseVersion="$(FileVersion)">
      <Output TaskParameter="Version" PropertyName="FileVersion" />
    </GetCurrentBuildVersion>
    <PropertyGroup>
      <AssemblyVersion>$(FileVersion)</AssemblyVersion>
    </PropertyGroup>
  </Target>
 
</Project>

重要的事情在这里:

  • 提到UsingTaskDC.Build.Tasks.dll导入GetCurrentBuildVersion任务。它假定此dll文件位于您的.csproj文件的父目录中。
  • 如果在解决方案中有更多项目调用GetCurrentBuildVersion任务,则我们的BeforeBuildActionsProject1目标调用任务必须在每个项目中具有唯一的名称。

该解决方案的优势在于它不仅可以在构建服务器上的构建中使用,而且还可以在dotnet构建或Visual Studio 中的手动构建中使用。


4
我建议使用DateTime.UtcNow的,而不是DateTime.Now在方法GetCurrentBuildVersionString(),如果在自动生成的机器代码执行特别。当您的计算机切换到夏令时或从夏令时切换时,它们可能会在凌晨2点或凌晨3点运行。随着DateTime.Now在那种情况下,你可能会在版本方面将倒退。诚然,这是一个极端的案例,我也承认我很挑剔。:-)而且,如果在所有构建机器上配置相同的时区并且不适应夏令时,问题也将消失。
曼弗雷德

是否有为此的NuGet包?
乔纳森·艾伦

@Jonathan Allen不,我没有nuget包的计划,因为每个项目的名称不同。您可以在github.com/holajan/DC.Build.Tasks/tree/master/dist文件夹中下载已编译的构建任务assemby
HolaJan

我们一直在使用自定义控制台应用程序从服务器获取我们的版本,并在构建之前生成AssemblyInfo.cs文件。这种方法非常适合我们的工作。您是否能够使用此方法在新项目的打包功能的“版本”中推送版本?很好,但是我想我们也可以使用nuget.exe进行打包,因为我们也需要发布它。
David Ritchie '18

15

您可以使用MSBuild属性函数根据当前日期设置版本后缀:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
  <VersionSuffix>pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))</VersionSuffix>
</PropertyGroup>

这将输出一个名称如下的包:PackageName.1.0.0-pre20180807-1711.nupkg

有关MSBuild属性函数的更多详细信息: https //docs.microsoft.com/zh-cn/visualstudio/msbuild/property-functions

Version是从组合形成VersionPrefixVersionSuffix,或者,如果VersionSuffix是空的,VersionPrefix只。

<PropertyGroup>
  <VersionPrefix>1.0.0</VersionPrefix>
</PropertyGroup>

这真的很方便
杰里·尼克松

11

我接受了以上答案,因为@Gigi是正确的(到目前为止),但是我很烦恼,并提出了以下PowerShell脚本。

首先,我在解决方案文件夹(UpdateBuildVersion.ps1)中有脚本:

#Get Path to csproj
$path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj"

#Read csproj (XML)
$xml = [xml](Get-Content $path)

#Retrieve Version Nodes
$assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion
$fileVersion = $xml.Project.PropertyGroup.FileVersion

#Split the Version Numbers
$avMajor, $avMinor, $avBuild  = $assemblyVersion.Split(".")
$fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".")

#Increment Revision
$avBuild = [Convert]::ToInt32($avBuild,10)+1
$fvBuild = [Convert]::ToInt32($fvBuild,10)+1

#Put new version back into csproj (XML)
$xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild"
$xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild"

#Save csproj (XML)
$xml.Save($path)

我将此添加到csproj文件:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <AssemblyVersion>0.0.1</AssemblyVersion>
    <FileVersion>0.0.1</FileVersion>
    <PreBuildEvent>powershell.exe NonInteractive ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"</PreBuildEvent>
  </PropertyGroup>
</Project>

即使将其设置为PreBuildEvent,事实是直到将文件加载到内存中之后,版本号才会更新,因此,直到下一次构建之前,版本号才会反映出来。实际上,您可以将其更改为PostBuildEvent,并且具有相同的效果。

我还创建了以下两个脚本:(UpdateMinorVersion.ps1)

#Get Path to csproj
$path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj"

#Read csproj (XML)
$xml = [xml](Get-Content $path)

#Retrieve Version Nodes
$assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion
$fileVersion = $xml.Project.PropertyGroup.FileVersion

#Split the Version Numbers
$avMajor, $avMinor, $avBuild  = $assemblyVersion.Split(".")
$fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".")

#Increment Minor Version - Will reset all sub nodes
$avMinor = [Convert]::ToInt32($avMinor,10)+1
$fvMinor = [Convert]::ToInt32($fvMinor,10)+1
$avBuild = 0
$fvBuild = 0

#Put new version back into csproj (XML)
$xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild"
$xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild"

#Save csproj (XML)
$xml.Save($path)

(UpdateMajorVersion.ps1)

#Get Path to csproj
$path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj"

#Read csproj (XML)
$xml = [xml](Get-Content $path)

#Retrieve Version Nodes
$assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion
$fileVersion = $xml.Project.PropertyGroup.FileVersion

#Split the Version Numbers
$avMajor, $avMinor, $avBuild  = $assemblyVersion.Split(".")
$fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".")

#Increment Major Version - Will reset all sub nodes
$avMajor = [Convert]::ToInt32($avMajor,10)+1
$fvMajor = [Convert]::ToInt32($fvMajor,10)+1
$avMinor = 0
$fvMinor = 0
$avBuild = 0
$fvBuild = 0

#Put new version back into csproj (XML)
$xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild"
$xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild"

#Save csproj (XML)
$xml.Save($path)

10

dotnet版本/p:AssemblyVersion=1.2.3.4

我的回答是:“有人知道如何控制.NET Core(或相应的.NETStandard)项目中的版本。” 我发现此问题试图在CI构建的上下文中解决此问题。我想将程序集版本设置为CI内部版本号。


1
标题为“ Visual Studio 2017(.NET Core)中的自动版本控制”。手动构建的确切位置符合“ Visual Studio 2017”?
JCKödel

4
我的回答是:“有人知道如何控制.NET Core(或相应的.NETStandard)项目中的版本。” 我发现此问题试图在CI构建的上下文中解决此问题。我想将程序集版本设置为CI内部版本号。很抱歉,如果您觉得这与眼前的问题无关。
克里斯·麦肯齐

对我来说,这是一个有用的组件。我将其用作CI解决方案的一部分
Mark Adamson

1
@ChrisMcKenzie:您的评论中应包含您的评论,以使您的意图清楚
Michael Freidgeim

**当未指定assemblyinfo.cs且版本位于csproj中时,这在netstandard项目上对我不起作用...
tofutim

9

这些值现在在.csproj文件中设置:

<PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <AssemblyVersion>1.0.6.0</AssemblyVersion>
    <FileVersion>1.0.6.0</FileVersion>
    <Version>1.0.1</Version>
</PropertyGroup>

如果进入项目设置的“ 软件包”选项卡,这些值将与您看到的相同。虽然我认为您不能*用来自动增加版本,但是您可以做的是引入一个后处理步骤来替您替换版本(例如,作为持续集成的一部分)。


6
我担心这将是答案。我将看看是否可以执行预构建步骤来增加它。
詹森·H

3
正如另一个线程所指出的那样,新的csproj格式允许您关闭Assemblyinfo文件的自动生成,并可以指定自己的文件。我跟着natemcmaster的答案的建议在这里和使用的标准AssemblyInfo.cs文件:stackoverflow.com/questions/42138418/...
詹姆斯伊比

5
他们为什么要删除自动增量?对于我来说,它确实运行得很好,而且非常简单。我推送主文件,CI生成并递增,然后使用某些PS脚本直接从生成的DLL中读取版本,然后在推送至NuGet时将该版本用作arg。很简单。现在坏了。
路加·普普利特

1
@LukePuplett同样在这里。太令人沮丧了!
Shimmy Weitzhandler '10 / 10/10

@LukePuplett:请参阅[“ .Net Core#22660上的AssemblyVersion中的通配符混淆错误消息”](github.com/dotnet/roslyn/issues/22660),blog.paranoidcoding.com中描述了他们认为确定性构建有益的原因。/ 2016/04/05 /…和编译器应该是确定性的:相同的输入生成相同的输出#372 < github.com/dotnet/roslyn/issues/372 >
Michael Freidgeim

5

我制作了一个简单的CLI工具,用于在此处设置.csproj .NET Core版本字符串。您可以将其与GitVersion之类的工具结合使用,以在CI构建期间自动进行版本升级。


@JasonH谢谢,如果您有任何问题,请告诉我。
Tagc

该死的天才。爱它!
pms1969

4

使用GIT的标记/描述功能,基于GIT设置启用.Net Core / .Net任意项目的版本控制。

我一直在使用Prebuild.targets.xml文件,该文件位于项目的根文件夹中,并包含在csproj文件中,例如:

<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="PreBuild.targets.xml" />
  ...
  <PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>

使用“ GenerateAssembyInfo”标签禁用自动装配信息的生成。

然后,Prebuild.targets.xml将生成一个CommonAssemblyInfo.cs文件,您可以在其中包含基于GIT版本的所需版本标签。

注意:我在其他地方找到了Prebuilds.targets.xml,因此不必费心清理它。)

Prebuild.targets.xml文件:

    <?xml version="1.0" encoding="utf-8" ?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

      <UsingTask
        TaskName="GetVersion"
        TaskFactory="CodeTaskFactory"
        AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
        <ParameterGroup>
          <VersionString ParameterType="System.String" Required="true" />
          <Version ParameterType="System.String" Output="true" />
          <Commit ParameterType="System.String" Output="true" />
          <VersionSuffix ParameterType="System.String" Output="true" />
        </ParameterGroup>
        <Task>
          <!--<Reference Include="" />-->
          <Using Namespace="System"/>
          <Using Namespace="System.IO"/>
          <Using Namespace="System.Text.RegularExpressions" />
          <Code Type="Fragment" Language="cs">
            <![CDATA[
              var match = Regex.Match(VersionString, @"^(?<major>\d+)\.(?<minor>\d+)(\.?(?<patch>\d+))?-(?<revision>\d+)-(?<commit>[a-z0-9-]+)$");
              int major, minor, patch, revision;
              Int32.TryParse(match.Groups["major"].Value, out major);
              Int32.TryParse(match.Groups["minor"].Value, out minor);
              Int32.TryParse(match.Groups["patch"].Value, out patch);
              Int32.TryParse(match.Groups["revision"].Value, out revision);
              _Version = new Version(major, minor, patch, revision).ToString();
              _Commit = match.Groups["commit"].Value;
            ]]>
          </Code>
        </Task>
      </UsingTask>

      <UsingTask
        TaskName="GitExistsInPath"
        TaskFactory="CodeTaskFactory"
        AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
        <ParameterGroup>
          <Exists ParameterType="System.Boolean" Output="true" />
        </ParameterGroup>
        <Task>
          <!--<Reference Include="" />-->
          <Using Namespace="System"/>
          <Using Namespace="System.IO"/>
          <Using Namespace="System.Text.RegularExpressions" />
          <Code Type="Fragment" Language="cs">
            <![CDATA[
            var values = Environment.GetEnvironmentVariable("PATH");
            foreach (var path in values.Split(';')) {
                var exeFullPath = Path.Combine(path, "git.exe");
                if (File.Exists(exeFullPath)) {
                    Exists = true;
                    return true;
                }
                var cmdFullPath = Path.Combine(path, "git.cmd");
                if (File.Exists(cmdFullPath)) {
                    Exists = true;
                    return true;
            }
            }
            Exists = false;
            ]]>
          </Code>
        </Task>
      </UsingTask>

      <Target Name="CreateCommonVersionInfo" BeforeTargets="CoreCompile">
        <Message Importance="high" Text="CreateCommonVersionInfo" />

        <GitExistsInPath>
          <Output TaskParameter="Exists" PropertyName="GitExists"/>
        </GitExistsInPath>
        <Message Importance="High" Text="git not found!" Condition="!$(GitExists)"/>

        <Exec Command="git describe --tags --long --dirty > $(ProjectDir)version.txt" Outputs="$(ProjectDir)version.txt" WorkingDirectory="$(SolutionDir)" IgnoreExitCode="true" Condition="$(GitExists)">
          <Output TaskParameter="ExitCode" PropertyName="ExitCode" />
        </Exec>
        <Message Importance="high" Text="Calling git failed with exit code $(ExitCode)" Condition="$(GitExists) And '$(ExitCode)'!='0'" />

        <ReadLinesFromFile File="$(ProjectDir)version.txt" Condition="$(GitExists) And '$(ExitCode)'=='0'">
          <Output TaskParameter="Lines" ItemName="OutputLines"/>
        </ReadLinesFromFile>
        <Message Importance="High" Text="Tags: @(OutputLines)" Condition="$(GitExists) And '$(ExitCode)'=='0'"/>

        <Delete Condition="Exists('$(ProjectDir)version.txt')" Files="$(ProjectDir)version.txt"/>

        <GetVersion VersionString="@(OutputLines)" Condition="$(GitExists) And '$(ExitCode)'=='0'">
          <Output TaskParameter="Version" PropertyName="VersionString"/>
          <Output TaskParameter="Commit" PropertyName="Commit"/>
        </GetVersion>

        <PropertyGroup>
          <VersionString Condition="'$(VersionString)'==''">0.0.0.0</VersionString>
        </PropertyGroup>

        <Message Importance="High" Text="Creating CommonVersionInfo.cs with version $(VersionString) $(Commit)" />

        <WriteLinesToFile Overwrite="true" File="$(ProjectDir)CommonAssemblyInfo.cs" Encoding="UTF-8" Lines='using System.Reflection%3B

    // full version: $(VersionString)-$(Commit)

    [assembly: AssemblyVersion("$(VersionString)")]
    [assembly: AssemblyInformationalVersion("$(VersionString)")] 
    [assembly: AssemblyFileVersion("$(VersionString)")]' />

      </Target>
    </Project>

编辑:如果您正在使用MSBUILD构建

 $(SolutionDir)

可能会给您带来麻烦,请使用

 $(ProjectDir)

代替


真好!是否会设置或使用VersionSuffix?好像不是
Mark Adamson

4

您可以在csproj文件中执行以下操作。我没有弄清楚数学。我发现在stackoverflow上的其他地方。但这有效,并且会给您一些类似于1.0。*的版本。

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <FileVersion>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays).$([System.Math]::Floor($([MSBuild]::Divide($([System.DateTime]::UtcNow.TimeOfDay.TotalSeconds), 1.32))))</FileVersion>
    <Version>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays)</Version>
</PropertyGroup>

3

Visual Studio的自动版本扩展现在在简单的用户界面中支持.Net Core和.Net Standard自动增量。

https://marketplace.visualstudio.com/items?itemName=PrecisionInfinity.AutomaticVersions


1
我已经使用演示解决方案(Windows应用程序)进行了快速测试,并且可以与.net标准项目一起使用。这是一项快速测试,因此必须更深入地研究我们是否想要做的所有事情。但是您可以尝试使用此方法。
ArieKanarie

2

我们可以使用特殊参数 dotnet publish -- version-suffix 1.2.3

对于文件版本:

<AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</AssemblyVersion>
<AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>

对于版本:

<Version Condition=" '$(VersionSuffix)' == '' ">0.0.1</Version>
<Version Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</Version>

https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish?tabs=netcore21

--version-suffix <VERSION_SUFFIX>     Defines the value for the $(VersionSuffix) property in the project.

2

感谢@joelsand为我指出正确的方向。

在运行DevOps Build时,我不得不略微更改他的答案,但出现以下异常

The specified version string does not conform to the recommended format - major.minor.build.revision

我必须在major.minor.build部分的末尾添加$(BUILD_BUILDNUMBER)。要删除实际版本,我还使用了版本前缀:

<PropertyGroup>
    <VersionPrefix>1.0.3</VersionPrefix>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">$(VersionPrefix)-local</Version>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(VersionPrefix)-$(BUILD_BUILDNUMBER)</Version>
</PropertyGroup>

我有相同的确切问题,您的回答已解决。谢谢。
会议

1

我觉得这个答案从@joelsand是设置版本号在VSTS运行DOTNET核心正确答案

要为此答案添加更多信息,

BUILD_BUILDNUMBER实际上是一个预定义变量

事实证明,预定义变量有2个版本。

一个是build.xxxx,另一个是BUILD_XXXX。

您只能Environment Variable Name在cproj中使用。


build.xxxx前端不使用它在管道中进行引用,BUILD_XXXX它的值是否相同,但是在PS中引用变量需要稍微修改语法?
dst3p
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.