【问题标题】:MSBuild auto increment build version differently for release/debugMSBuild 以不同方式自动递增构建版本以进行发布/调试
【发布时间】:2020-03-25 04:34:37
【问题描述】:

上下文:

我使用 MSBuild 来构建我的项目。目前我使用的版本号发布日期,不幸的是,当多个版本在同一天发生时,它缺乏明确性。在Directory.Build.props:

  <PropertyGroup>
    <Version>
      $([System.DateTime]::Now.Year).
      $([System.DateTime]::Now.Month).
      $([System.DateTime]::Now.Day).
      $([System.Convert]::ToUInt16(
          $([MSBuild]::Divide(
              $([System.DateTime]::Now.TimeOfDay.TotalSeconds),
              1.32
          ))
      ))
    </Version>
  </PropertyGroup>

目标:

创建如下所示的版本控制方案:

20 年 3 月 23 日:

  • 发布版本:2020.3.23.0

20 年 3 月 24 日:

  • 调试版本:2020.3.24.0
  • 调试版本:2020.3.24.1
  • 调试版本:2020.3.24.2
  • 发布版本:2020.3.24.0
  • 调试版本:2020.3.24.3
  • 发布版本:2020.3.24.1

基本上:前三个数字是年/月/日,因为发布日期通常很重要。然后使用自动递增的版本号在同一天内发布。调试增量很有用,因此我可以确认正在加载和运行正确版本的软件,但我不希望发布版本中出现令人困惑的高数字。我可能会尝试一些额外的调试构建指标,但我应该能够自己解决。

问题:

如何在同一天自动增加构建版本,并为调试和发布提供单独的版本?理想情况下,不添加额外依赖的解决方案是首选,但如果没有no,那么它是可以接受的。

【问题讨论】:

  • 请编辑您的问题,以客观的方式明确说明您的“最佳方式”指标是什么。
  • @TylerH 将其更改为“最简单”而不是“最佳”,并添加了我能想到的唯一规定。虽然我觉得这里的“最佳”是相当不言自明的,因为“通常遵循良好的编码实践和常识”。
  • 问题是良好的编码习惯因人而异。当然,常识也是一个不同的东西。最简单的稍微好一点,但仍然模糊。你的意思是代码行数最少吗?最少的依赖项(如您提到的其他软件包)?等等。客观性的一个很好的指导是:如果一个新手和一个 20 年的专业人士都看这个问题,他们会为你的要求提出相同的描述吗?他们是否都同意给定的解决方案满足问题陈述的需求?等等。
  • @TylerH 这感觉很挑剔。最简单显然不可能客观地定义 100%。最少的代码行很可能是超级不清楚和hacky。鉴于此,我将对其进行更改以消除所有主观性 - 任何有效的答案都可以。
  • "最简单显然不可能定义 100% 目标" 没错!这就是为什么你应该跳过“最简单”、“最好”、“最惯用”等术语,而只是询问你的意思是什么客观可回答的术语:-)

标签: c# visual-studio msbuild


【解决方案1】:

MSBuild 自动递增构建版本以不同方式进行发布/调试

一般来说,MSBuild没有查看明显增量构建的版本号的功能,只是使用系统构建的时间戳决定了之前使用的构建顺序。

其实,如果在msbuild中创建自定义属性来记录增量构建的版本号,还是需要使用实体来存储记录,如果不使用,每次构建都会重新初始化参数(msbuild 属性只能在 msbuild 中识别)。

因此,使用文本文件作为中间文件的理想方式。您可以按照我的解决方案:

解决方案

1) 创建a custom msbuild task,它确实会增加记录属性的值。

--a) 创建一个名为MyCustomTask 的类库项目,然后右键单击该项目-->添加引用-->引用Microsoft.Build.Framework dll 和Microsoft.Build.Utilities.v4.0 dll。

--b) 将这些添加到CustomTask.cs(这是将在xxx.csproj 文件中使用的任务的名称)。

 public class CustomTask : Task
        {

            private int _number;
            [Required]
            public int number   //input taskitem
            {
                get { return _number; }

                set { _number = value; }

            }
            private int _lastnumber;
            [Output]
            public int LastNumber   //output value
            {
                get { return _lastnumber; }
                set { _lastnumber = value; }
             }

            public override bool Execute()   // Execution logic 
            {
                LastNumber = number + 1;
                return true;
            }
        }

--c) 然后构建项目并记住存储它的MyCustomTask dll。

2) 瞄准您的主项目,然后创建两个名为Debug.txt、Release.txt 的txt 文件,并为每个文件赋予0 的初始值。

3) 将这些添加到您的 Directory.Build.props 文件中:

<Project>
  <UsingTask TaskName="CustomTask" AssemblyFile="xxxxxx\MyCustomTask\MyCustomTask\MyCustomTask\bin\Debug\MyCustomTask.dll(the local path of the dll)"> </UsingTask>    
  <PropertyGroup>
    <Record></Record>
  </PropertyGroup>

    <Target Name="WriteToFile1"  BeforeTargets="PrepareForBuild">
      <PropertyGroup>
      <Record Condition="'$(Configuration)'=='Debug' and !Exists('$(TargetPath)')">
        0
      </Record>
      <Record Condition="'$(Configuration)'=='Release'and !Exists('$(TargetPath)')">
        0
      </Record>
      </PropertyGroup>
      <ItemGroup Condition="'$(Configuration)'=='Debug'"> 
        <MyTextFile Include="Debug.txt">
        <Number>$(Record)</Number>
        </MyTextFile>
      </ItemGroup>
      <ItemGroup Condition="'$(Configuration)'=='Release'">
        <MyTextFile Include="Release.txt">
          <Number>$(Record)</Number>
        </MyTextFile>
      </ItemGroup>
      <WriteLinesToFile
        File="@(MyTextFile)"
        Lines="$(Record)"
        Overwrite="true"
        Encoding="Unicode" Condition="'$(Configuration)'=='Debug'"/>
      <WriteLinesToFile
        File="@(MyTextFile)"
        Lines="$(Record)"
        Overwrite="true"
        Encoding="Unicode" Condition="'$(Configuration)'=='Release'"/>
      <PropertyGroup>
        <Version>
          $([System.DateTime]::Now.Year).
          $([System.DateTime]::Now.Month).
          $([System.DateTime]::Now.Day).
          $(Record)
        </Version>
      </PropertyGroup>
    </Target>

  <Target Name="ReadLineFromFile" BeforeTargets="WriteToFile1">
    <ReadLinesFromFile File="Debug.txt" Condition="'$(Configuration)'=='Debug'">
      <Output TaskParameter="Lines" PropertyName="Record"/>
    </ReadLinesFromFile>
    <ReadLinesFromFile File="Release.txt" Condition="'$(Configuration)'=='Release'">
      <Output TaskParameter="Lines" PropertyName="Record"/>
    </ReadLinesFromFile>

    <CustomTask number="$(Record)">
      <Output TaskParameter="LastNumber" PropertyName="Record"/>
    </CustomTask>
    </Target>
</Project>

4) 当你执行一个依赖于 Build 来显示属性 Version 的任务时,它会如你所愿地工作。

注意,它适用于增量构建,如果您点击Rebuild(执行清理然后构建),它会将版本号设置为零并开始重新抛出。

总的来说,这是一个理想的解决方案,我正在努力实现它。

【讨论】:

  • 谢谢,这对我来说是一个非常有用的开始,并帮助解决了我在此过程中遇到的几个问题。我为我的个人实现做了一些更改,特别是:我使用了一个内联任务而不是一个单独的项目,并将以前的版本存储在 $(IntermediateOutputPath) 中的 JSON 文件中。再次感谢您为此付出的努力。
猜你喜欢
  • 2018-09-08
  • 1970-01-01
  • 2014-01-22
  • 2019-08-25
  • 1970-01-01
  • 2019-05-16
  • 2012-10-26
  • 1970-01-01
  • 2010-11-07
相关资源
最近更新 更多