116

私自身と私のグループは、アセンブリのバージョン番号を増やすのが苦手で、バージョン 1.0.0.0 のアセンブリを頻繁に出荷しています。明らかに、これは多くの頭痛を引き起こします。

CIプラットフォームを介してプラクティスを大幅に改善しており、assemblyinfo.csファイル内の値を自動インクリメントするように設定して、アセンブリのバージョンがそのアセンブリのコード変更で自動更新されるようにしたいと考えています。

私は以前に ( Hudsonmsbuildを見つける前に)またはコマンドライン (思い出せません)を使用して値をインクリメントする方法をセットアップしていましたが、Hudson を使用すると、SVN リポジトリが更新され、別のビルドがトリガーされます。Hudson が SVN を 1 時間ごとにポーリングするため、低速の無限ループが発生します。

Hudson にバージョン番号をインクリメントさせるのは悪い考えですか? それを行う別の方法は何ですか?

理想的には、解決策の基準は次のとおりです。

  • assemblyinfo.csビルドの前にビルド番号をインクリメントします
  • 変更されたアセンブリのビルド番号のみをインクリメントします。Hudson はビルドを行うたびにプロジェクト フォルダーを消去するため、これは不可能な場合があります。
  • 変更された assemblyinfo.cs をコード リポジトリ (現在はVisualSVN )にコミットします。
  • 次回変更をスキャンするときに、Hudson が新しいビルドをトリガーしないようにします。

これを頭の中で考えてみると、バッチ ファイルやコマンドを使用して、ほとんどの解決策を簡単に思いつくことができましたが、私の考えではすべて、次回のスキャン時に Hudson が新しいビルドをトリガーすることになります。私は私のためにすべてをやってくれる人を探しているわけではありません。正しい方向に私を向けるだけです。ハドソンに特定の SVN コミットを無視させるテクニックなどです。

これまでに見つけたものはすべて、バージョン番号を自動的にインクリメントする方法を説明する記事にすぎず、無限ループに陥る可能性のある CI プラットフォームは考慮されていません。

4

12 に答える 12

66

AssemblyFileVersion属性をスタンプするために私が行ったことは次のとおりです。

AssemblyInfo.csからAssemblyFileVersionを削除しました

AssemblyFileInfo.csという名前の新しい空のファイルをプロジェクトに追加します。

MSBuildコミュニティタスクツールセットをhudsonビルドマシンにインストールするか、プロジェクトの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>

Hudsonは、プロジェクトがhudson上に構築されているときに表示される環境変数を提供します(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を取得します。これは、Hudsonの6番目のビルド#を意味します。

于 2010-08-18T22:10:31.530 に答える
42

これは、新しいプロジェクトを追加するときに事前に少し作業が必要ですが、プロセスを非常に簡単に処理するエレガントなソリューションです。

各プロジェクトは、アセンブリのバージョン情報のみを含むソリューション ファイルにリンクするという考え方です。したがって、ビルド プロセスは 1 つのファイルを更新するだけで済み、すべてのアセンブリ バージョンはコンパイル時に 1 つのファイルからプルされます。

手順:

  1. ソリューション ファイル *.cs ファイルにクラスを追加します。min SharedAssemblyProperties.cs という名前を付けました。
  2. その新しいファイルからすべてのcs情報を削除します
  3. AssemblyInfo ファイルからアセンブリ情報を切り取ります: [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
  4. 「using System.Reflection;」というステートメントを追加します。ファイルにコピーし、データを新しい cs ファイル (例: SharedAssemblyProperties.cs) に貼り付けます。
  5. プロジェクトに既存のアイテムを追加します (ファイルを追加する前に読んでください)。
  6. ファイルを選択し、[追加] をクリックする前に、追加ボタンの横にあるドロップダウンをクリックし、[リンクとして追加] を選択します。
  7. ソリューション内のすべての既存および新規プロジェクトについて、手順 5 と 6 を繰り返します。

ファイルをリンクとして追加すると、データがプロジェクト ファイルに格納され、コンパイル時にこの 1 つのファイルからアセンブリ バージョン情報が取得されます。

ソース管理では、単に SharedAssemblyProperties.cs ファイルをインクリメントするバット ファイルまたはスクリプト ファイルを追加すると、すべてのプロジェクトがそのファイルからアセンブリ情報を更新します。

于 2010-02-04T16:23:41.080 に答える
11

Hudson は、特定のパスとファイルへの変更を無視するように構成できるため、新しいビルドが要求されません。

ジョブ構成ページの[ソース コード管理] で、[詳細設定] ボタンをクリックします。[除外された地域]ボックスに、除外に一致する 1 つ以上の正規表現を入力します。

たとえば、version.propertiesファイルへの変更を無視するには、次を使用できます。

/MyProject/trunk/version.properties

これは C# 以外の言語でも機能し、バージョン情報を Subversion 内に保存できます。

于 2009-07-22T07:15:30.503 に答える
8

1.0。*機能がVS2005またはVS2008で機能するのを実際に見たことがありません。値をインクリメントするようにVSを設定するために実行する必要があることはありますか?

AssemblyInfo.csが1.0。*でハードコーディングされている場合、実際のビルド/リビジョンはどこに保存されますか?

AssemblyInfoに1.0。*を配置した後、ProductVersionの値が無効になっているため、次のステートメントを使用できません。VSによって割り当てられた値ではなく1.0。*を使用しています。

Version version = new Version(Application.ProductVersion);

ため息-これは誰もが尋ねるものの1つであるように思われますが、どういうわけか確かな答えはありません。数年前、ビルド後のプロセスの一部として、リビジョン番号を生成してAssemblyInfoに保存するためのソリューションを見ました。VS2008ではこのようなダンスは必要ないのではないかと思いました。多分VS2010?

于 2009-10-15T23:43:41.023 に答える
6

以下の 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#>")]
于 2013-02-03T23:23:04.413 に答える
3

MikeS の回答の続きとして、これを機能させるには VS + Visual Studio Visualization and Modeling SDK をインストールする必要があり、プロジェクト ファイルも変更する必要があることを追加したいと思いました。また、バージョンモジュールを備えたWindows 2008 R2サーバーボックスで実行されるビルドサーバーとしてJenkinsを使用し、BUILD_NUMBERを取得することにも言及する必要があります。

私のテキストテンプレートファイル 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>

このようにして、ビルドと変更セットを追跡できるため、最後のビルド以降に何もチェックインしていない場合、最後の桁は変更されませんが、ビルドプロセスに変更を加えた可能性があるため、最後から2番目の数字が必要です. もちろん、ビルドの前に複数のチェックインを行うと、最後の変更のみがバージョンに反映されます。それを連結できると思いますが必要です。

もっと手の込んだことをして、tt テンプレート内から直接 TFS を呼び出すことができると確信していますが、これは私にとってはうまくいきます。

次に、このように実行時にバージョンを取得できます

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return fvi.FileVersion;
于 2014-04-03T01:34:31.773 に答える
1

したがって、バージョン番号が異なるアセンブリを持つ複数のプロジェクトを含む 1 つのソリューションを持つプロジェクトがあります。

上記の方法のいくつかを調査した後、AssemblyInfo.cs ファイルで検索と置換を行う Powershell スクリプトを実行するビルド ステップを実装しました。私は今でもソース管理で 1.0.* のバージョン番号を使用しており、Jenkins は 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" オプションを追加したのは、そうしなかった場合、git が .cs ファイルをバイナリ ファイルとして扱い始めたためです。確かに、実際に結果をコミットしたことはないので、これは問題ではありませんでした。私がテストしていたときに出てきました。

私たちの CI 環境には、Jenkins ビルドを特定の git コミットに関連付ける機能が既に備わっているため (Stash プラグインに感謝します!)、バージョン番号が添付された git コミットがないことを心配する必要はありません。

于 2016-04-25T16:38:32.430 に答える
1

私のソリューションでは、外部ツールやスクリプト言語を追加する必要はありません。ビルド マシンで動作することがほぼ保証されています。この問題をいくつかの部分で解決します。まず、Jenkins の BUILD_NUMBER パラメータを環境変数に変換する BUILD.BAT ファイルを作成しました。Jenkins の「Windows バッチ コマンドの実行」機能を使用して、Jenkins ビルドに関する次の情報を入力して、ビルド バッチ ファイルを実行します。

     ./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%

ビルドの好みに合わせて調整する必要があるかもしれません。プロジェクトを手動で 1 回ビルドして、メイン プロジェクトの Properties ディレクトリに初期 Version.cs ファイルを生成します。最後に、そのプロジェクトの [プロパティ] タブの下にある [ソリューション エクスプローラー] ペインに Version.cs ファイルをドラッグして、手動で Visual Studio ソリューションに含めます。将来のビルドでは、Visual Studio は Jenkins のビルド時にその .cs ファイルを読み取り、そこから正しいビルド番号情報を取得します。

于 2014-05-24T00:37:19.927 に答える
0

これはより単純なメカニズムです。これには、MSBuildステップの前にWindowsバッチコマンドタスクビルドステップを追加し、単純な検索と置換プログラム(FART)を使用するだけです。

バッチステップ

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以外のソース管理を使用している場合は、scm環境に適した--svnオプションを変更してください。

おならをダウンロード

于 2012-09-04T02:47:11.727 に答える