我怎么能自动通过我们的CI平台(哈德森)递增C#程序集版本?(How can I auto incr

2019-06-25 22:33发布

我和我的团队都在递增程序集版本号可怕的,我们常常附带1.0.0.0版本的组件。 很显然,这会导致很多麻烦。

我们得到了很多与我们的做法,更好地通过我们的CI平台,我真的很想给内将它设置为自动增量值assemblyinfo.cs文件,这样我们的组件的版本是自动的代码变化更新该程序集。

我以前有安装(我们发现前哈德森 )的方式来增加通过任一值msbuild或命令行(记不清了),但与哈德森,会更新SVN仓库并引发另一个构建。 这将导致一个缓慢的无限循环作为哈德逊民意调查SVN每小时。

是具有哈德森增加版本号是一个坏主意? 什么是另一种方式做到这一点?

理想情况下,我的一个解决方案的标准将是一个:

  • 递增的版本号assemblyinfo.cs构建之前
  • 只有增加已改变了组件的版本号。 这是不可能的,如Hudson每它的生成时间抹了项目文件夹
  • 提交变更后的AssemblyInfo.cs到代码库(目前的VisualSVN )
  • 不会造成哈德森它扫描更改下一次触发新的构建

工作这一点在我的头上,我可以很容易地想出通过批处理文件/命令解决这个最,但所有我的想法会导致哈德森它扫描下一次引发新的版本。 我不是在找人来为我做的一切,只是点我朝着正确的方向,也许技术让哈德森忽略某些SVN提交等。

到目前为止,我发现一切都只是一篇文章,解释如何得到的版本号自动递增,没有考虑到一个CI平台,可纺成一个无限循环。

Answer 1:

一个简单的办法是让C#环境设置版本属性递增大会版本供您major.minor.* (如集信息文件模板描述。)

你可能会寻找一个更全面的解决方案,虽然。

编辑 (回答这个问题在注释):

AssemblyInfo.cs

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]


Answer 2:

下面是我做什么,对冲压的AssemblyFileVersion属性。

从删除的AssemblyInfo.cs中的AssemblyFileVersion

添加一个新的,空的,文件名为AssemblyFileInfo.cs到项目中。

安装的MSBuild社区任务哈德森生成计算机上或作为一个工具集的NuGet依赖于您的项目。

编辑项目(的csproj)文件,它只是一个MSBuild文件,并添加以下。

某处就会有一个<PropertyGroup>说明的版本。 改变这种状况,所以它读取如

 <Major>1</Major>
 <Minor>0</Minor>
 <!--Hudson sets BUILD_NUMBER and SVN_REVISION -->
 <Build>$(BUILD_NUMBER)</Build>
 <Revision>$(SVN_REVISION)</Revision>

哈德森提供你瞧,当项目是建立在哈德森的ENV变量(假设它是从Subversion中取出)。

在项目文件的底部,添加

 <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')" />
  <Target Name="BeforeBuild" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')">
    <Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)" />
    <AssemblyInfo CodeLanguage="CS" OutputFile="AssemblyFileInfo.cs" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyConfiguration="$(Configuration)" Condition="$(Revision) != '' " />
  </Target>

它使用MSBuildCommunityTasks生成AssemblyFileVersion.cs到包括的AssemblyFileVersion属性项目建成之前。 你可以为任何的操作/如果你希望所有的版本属性。

其结果是,当你发出哈德森构建,所得到的组件获得的1.0.HUDSON_BUILD_NR.SVN_REVISION如1.0.6.2632一个的AssemblyFileVersion,这意味着哈德森6'th构建#,BUIT从Subversion版本2632。



Answer 3:

下面是需要一点点的前期工作增加了新的项目时,但很容易处理过程中的完美的解决方案。

这个想法是,每个项目链接到只包含组件的版本信息的解决方案文件。 所以,你的构建过程只需要更新单个文件和所有组件的版本从在编译时的一个文件中提取。

脚步:

  1. 一类添加到您的解决方案文件* cs文件,我命名分钟SharedAssemblyProperties.cs
  2. 从该新文件中删除所有的CS信息
  3. 切从集信息文件中的程序集的信息:[组件:的AssemblyVersion( “1.0.0.0”)] [组件:的AssemblyFileVersion( “1.0.0.0”)]
  4. 添加语句“使用的System.Reflection;” 该文件,然后将数据粘贴到新的CS文件(EX SharedAssemblyProperties.cs)
  5. 现有项目添加到您的项目(稍候......添加文件之前阅读)
  6. 选择文件并点击之前添加,单击下拉列表旁边的添加按钮,然后选择“添加链接”。
  7. 重复步骤5和6解决方案中的所有现有项目和新项目

当您添加文件的链接,它存储的数据在项目文件,并在编译时就会从这个文件中的程序集的版本信息。

在你的源代码控制,您添加只是增加了SharedAssemblyProperties.cs文件批处理文件或脚本文件和所有的项目都将更新该文件中的程序集的信息。



Answer 4:

哈德森可以被配置为忽略修改某些路径和文件,使其不提示了新的版本。

在工作中的配置页面,在源代码管理 ,单击高级按钮。 在排除地区框中输入一个或多个正则表达式匹配排除。

例如,要忽略更改version.properties文件,你可以使用:

/MyProject/trunk/version.properties

这会比C#以外的语言,并允许你存储颠覆内的版本信息。



Answer 5:

.NET做这个给你。 在你的AssemblyInfo.cs文件,请将您的组件版本MAJOR.MINOR *(例如:1.0 *)。

当你建立你的项目的版本是自动产生的。

构建和版本号是基于日期,使用UNIX时代产生的,我相信。 构建基于当前日期和修改是基于自午夜起的秒数。



Answer 6:

我从来没有真正看到1.0。*的功能在VS2005或VS2008的工作。 有什么需要做设置VS递增值是多少?

如果AssemblyInfo.cs中被硬编码1.0。*,然后在那里是真正的编译/修改保存在哪里?

。把1.0后*在集信息,我们不能使用下面的语句,因为现在的ProductVersion具有无效值 - 它使用1.0 *而不是VS赋值为:。

Version version = new Version(Application.ProductVersion);

叹息 - 这似乎是那些东西,大家问起但不知何故,从未有一个坚实的答案之一。 几年前,我看到了生成版本号,并将其保存到集信息作为生成后过程的一部分解决方案。 我希望那种舞将不需要为VS2008。 也许VS2010?



Answer 7:

我假设我们也可以用做文本模板 ,你创造有问题的程序集属性的飞行距离的环境下像AssemblyVersion.tt一样。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("SVN_REVISION");
revision = revision == null ? "0" : int.Parse(revision).ToString();    
#>
using System.Reflection;
[assembly: AssemblyVersion("1.0.<#=build#>.<#=revision#>")]
[assembly: AssemblyFileVersion("1.0.<#=build#>.<#=revision#>")]


Answer 8:

作为MIKES的回答的延续,我想补充一点,VS + Visual Studio的可视化和模拟SDK需要安装这个工作,你需要修改的项目文件中。 还应该提到我用詹金斯作为构建服务器上的版本模块,在这里我得到了一个BUILD_NUMBER的Windows 2008 R2服务器框中运行。

我的文本模板文件version.tt看起来是这样的

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("_BuildVersion");
revision = revision == null ? "5.0.0.0" : revision;    
#>
using System.Reflection;
[assembly: AssemblyVersion("<#=revision#>")]
[assembly: AssemblyFileVersion("<#=revision#>")]

我在属性组以下

<PropertyGroup>
    <TransformOnBuild>true</TransformOnBuild>
    <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

Microsoft.CSharp.targets的进口后,我有这个(取决于您安装VS的

<Import Project="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />

在我的构建服务器然后我有以下脚本运行实际构建之前的文本转换,以获得在TFS最后变更号码

set _Path="C:\Build_Source\foo"

pushd %_Path% 
"%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe" history . /r /noprompt /stopafter:1 /Version:W > bar
FOR /f "tokens=1" %%foo in ('findstr /R "^[0-9][0-9]*" bar') do set _BuildVersion=5.0.%BUILD_NUMBER%.%%foo
del bar
popd

echo %BUILD_NUMBER%
echo %_BuildVersion%
cd C:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\MyProject
MSBuild MyProject.csproj /t:TransformAll 
...
<rest of bld script>

这样我可以保持跟踪构建和变更,因此,如果我没有在自去年建立检查什么,最后一个数字应该不会改变,但是我可能已经更改了构建过程,因此需要进行的倒数第二个号码。 当然,如果你犯了一个构建之前多签入你只能得到体现在版本的最后一次更改。 我想你可以串联所需的。

我敢肯定,你可以做一些票友,并直接从TT模板中调用TFS,但是这对我的作品。

然后我可以在这样的运行得到我的版本

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return fvi.FileVersion;


Answer 9:

我的解决方案并不需要额外的外部工具或--IT几乎是保证您的构建机器上工作的脚本语言。 我在几个部分解决这个问题。 首先,我创建了詹金斯BUILD_NUMBER参数转换成一个环境变量BUILD.BAT文件。 我用詹金斯的“执行Windows批处理命令”功能来运行通过输入詹金斯构建以下信息生成批处理文件:

     ./build.bat --build_id %BUILD_ID% -build_number %BUILD_NUMBER%

在构建环境,我有开始如下一个文件的build.bat:

     rem build.bat
     set BUILD_ID=Unknown
     set BUILD_NUMBER=0
     :parse_command_line
     IF NOT "%1"=="" (
         IF "%1"=="-build_id" (
             SET BUILD_ID=%2
             SHIFT
             )
         IF "%1"=="-build_number" (
             SET BUILD_NUMBER=%2
             SHIFT
         )
         SHIFT
         GOTO :parse_command_line
     )
     REM your build continues with the environmental variables set
     MSBUILD.EXE YourProject.sln

一旦我做到了,我对这个项目右键单击要建在Visual Studio的解决方案资源管理器窗格中选择属性,选择生成事件,并输入以下信息作为预生成事件命令行,它会自动创建一个cs文件包含基于当前环境变量设置版本号信息:

     set VERSION_FILE=$(ProjectDir)\Properties\VersionInfo.cs
     if !%BUILD_NUMBER%==! goto no_buildnumber_set
     goto buildnumber_set
     :no_buildnumber_set
     set BUILD_NUMBER=0
     :buildnumber_set
     if not exist %VERSION_FILE% goto no_version_file
     del /q %VERSION_FILE%
     :no_version_file
     echo using System.Reflection; >> %VERSION_FILE%
     echo using System.Runtime.CompilerServices; >> %VERSION_FILE%
     echo using System.Runtime.InteropServices; >> %VERSION_FILE%
     echo [assembly: AssemblyVersion("0.0.%BUILD_NUMBER%.1")] >> %VERSION_FILE%
     echo [assembly: AssemblyFileVersion("0.0.%BUILD_NUMBER%.1")] >> %VERSION_FILE%

您可能需要调整到您的构建味道。 我生成项目手动一次生成主项目的属性目录中的初始Version.cs文件。 最后,我手动拖动到Solution Explorer窗格中,该项目的属性选项卡下包括Version.cs文件到Visual Studio解决方案。 在将来的版本时,Visual Studio然后读取的.cs在詹金斯文件建立的时间,并得到了正确的版本号信息出来。



Answer 10:

所以,我们有一个包含有不同版本号的组件的几个项目一个解决方案的项目。

调查几种上述方法后,我就实现了一个构建步骤来运行PowerShell脚本,做了查找和替换AssemblyInfo.cs文件。 我仍然使用1.0。*源代码控制版本号和詹金斯只是手动的MSBuild运行之前更新的版本号。

dir **/Properties/AssemblyInfo.cs | %{ (cat $_) | %{$_ -replace '^(\s*)\[assembly: AssemblyVersion\("(.*)\.\*"\)', "`$1[assembly: AssemblyVersion(`"`$2.$build`")"} | Out-File $_ -Encoding "UTF8" }
dir **/Properties/AssemblyInfo.cs | %{ (cat $_) | %{$_ -replace '^(\s*)\[assembly: AssemblyFileVersion\("(.*)\.\*"\)', "`$1[assembly: AssemblyFileVersion(`"`$2.$build`")"} | Out-File $_ -Encoding "UTF8" }

我添加了-Encoding“UTF8”选项,因为混帐开始治疗.cs文件为二进制文件,如果我没有。 当然,这并不重要,因为我从来没有真正提交结果; 它只是想出了,因为我是测试。

我们的CI环境已经有一个设施关联的詹金斯建立与特定git的承诺(感谢藏匿插件!),所以我不担心,有没有混帐与连接到它的版本号提交。



Answer 11:

这是一种简单的机制。 它只是涉及到另外的MSBuild步骤之前,Windows批处理命令任务生成步骤和使用简单的查找和替换程序(放屁)的。

本批步骤

fart --svn -r AssemblyInfo.cs "[assembly: AssemblyVersion(\"1.0.0.0\")]" "[assembly: AssemblyVersion(\"1.0.%BUILD_NUMBER%.%SVN_REVISION%\")]"
if %ERRORLEVEL%==0 exit /b 1
fart --svn -r AssemblyInfo.cs "[assembly: AssemblyFileVersion(\"1.0.0.0\")]" "[assembly: AssemblyFileVersion(\"1.0.%BUILD_NUMBER%.%SVN_REVISION%\")]"
if %ERRORLEVEL%==0 exit /b 1
exit /b 0

如果您使用的是其他比SVN改变一个合适你的供应链管理环境下的--svn选项源控制。

下载放屁



Answer 12:

我决定用几个方法使用预生成PowerShell脚本( https://gist.github.com/bradjolicoeur/e77c508089aea6614af3 )在每个成功的构建然后在Global.asax中,我会是这样的增量:

  // We are using debug configuration, so increment our builds.
  if (System.Diagnostics.Debugger.IsAttached)
  {
      string version = System.Reflection.Assembly.GetExecutingAssembly()
                                                       .GetName()
                                                       .Version
                                                       .ToString();

      var psi = new ProcessStartInfo(@"svn", "commit -m \"Version: " + version + "\n \"");
      psi.WorkingDirectory = @"C:\CI\Projects\myproject";
      Process.Start(psi); 
  }

我仍然认为整个过程过于复杂,我要去寻找到实现相同的结果的一个更有效的方法。 我想这主要是用于传递到版本SVN,然后到詹的没有太多addtional工具。



文章来源: How can I auto increment the C# assembly version via our CI platform (Hudson)?