6

問題: TeamCityをASP.NETMVCプロジェクトのビルドサーバーとして設定しています。Powershellとpsakeを使用して、.csprojファイルに対してmsbuildを実行し、デプロイ可能なパッケージを作成しています。ビルドサーバーから、PowerShellを開いてスクリプトを実行できます。ソースコードが変更されていないため、msbuildはプロジェクトDLLファイルを再生成しません。ただし、TeamCity Webインターフェイスからまったく同じスクリプトを呼び出すと、変更がない場合でも、msbuildは常にDLLファイルを再構築して再生成します。それがAFAIKをすべきではありません。

この問題を1つのステップに絞り込みました。簡単にするために、ソース管理を使用しないようにTeamCity構成を設定しました。これにより、PowerShellスクリプトを呼び出す単一の「PowerShell」ビルドステップが実行されます。

PowerShellスクリプトは、次の1つのコマンドを実行します。

exec { &$msbuild $ProjectFile /t:Package "/p:PackageLocation=$PackageFile;OutDir=$TempPath;Configuration=$Config;SolutionDir=$BaseDir\Source\" /v:m }

PowerShellコマンドラインからスクリプトを手動で呼び出すと、次のように表示されます。

CoreCompile:
Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.

TeamCityを介してまったく同じスクリプトを呼び出すと、次のように表示されます。

[11:11:26]: CoreCompile:
[11:11:26]:   c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig ...
<SNIP>
[11:11:32]: CopyFilesToOutputDirectory:
[11:11:32]:   Copying file from "obj\Demo\Website.Web.dll" to "d:\deploy\Build\package\Demo\temp\Website.Web.dll".
[11:11:32]:   Website.Web -> d:\deploy\Build\package\Demo\temp\Website.Web.dll
[11:11:32]:   Copying file from "obj\Demo\Website.Web.pdb" to "d:\deploy\Build\package\Demo\temp\Website.Web.pdb".
[11:11:32]: _CopyWebApplicationLegacy:
[11:11:32]:   Copying Web Application Project Files for Website.Web
[11:11:32]:   Copying file from "obj\Demo\Website.Web.dll" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Web.dll".
[11:11:32]:   Copying file from "obj\Demo\Website.Web.pdb" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Web.pdb".
[11:11:32]:   Copying file from "d:\deploy\Build\package\Demo\temp\Website.Data.dll" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Data.dll".
[11:11:32]:   Copying file from "d:\deploy\Build\package\Demo\temp\Website.Data.pdb" to "d:\deploy\Build\package\Demo\temp\_PublishedWebsites\Website.Web\bin\Website.Data.pdb".

TeamCityからこのスクリプトを実行すると、msbuildが変更を検出して再構築するのに、まったく同じスクリプトを手動で実行しない理由はありますか?

更新: これは、TeamCity Powershellランナーの癖が原因である可能性があると考えて、スクリプトをPowershell.exeに渡し、コマンドラインランナーを使用して呼び出すバッチファイルを作成してみました。

C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -File D:\deploy\Build\run-build.ps1 && exit /b %ERRORLEVEL%

まったく同じ動作になります。コマンドラインからこのバッチファイルを呼び出すと、msbuildはコンパイルをスキップします。TeamCityから呼び出すと、DLLが再コンパイルされます。

更新#2: ユーレカ!msbuildで診断デバッグをオンにして、強制的な再コンパイルの原因を見つけました。これは、GenerateTargetFrameworkMonikerAttributeターゲットが原因で発生します。ログ出力のキービットは次のとおりです。

[15:23:28]: Target "GenerateTargetFrameworkMonikerAttribute" in file "c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets" from project "d:\deploy\source\Website.Data\Website.Data.csproj" (target "BeforeCompile" depends on it):
[15:23:28]: Building target "GenerateTargetFrameworkMonikerAttribute" completely.
[15:23:28]: Output file "C:\TeamCity\buildAgent\temp\buildTmp\.NETFramework,Version=v4.0.AssemblyAttributes.cs" does not exist.
[15:23:28]: Using "WriteLinesToFile" task from assembly "Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
[15:23:28]: Task "WriteLinesToFile"
[15:23:28]: Done executing task "WriteLinesToFile".
[15:23:28]: Done building target "GenerateTargetFrameworkMonikerAttribute" in project "SMM.Data.csproj".

このターゲットは、TEMP環境変数で指定されているように、TEMPディレクトリにAssemblyAttributesファイルを作成/更新しているようです。どうやらTeamCityはTEMP環境変数をオーバーライドし、それをC:\ TeamCity \ buildAgent \ temp \ buildTmpに設定し、このディレクトリはすべてのビルドの前にクリーンアップされるようです。

これは、PowershellからGet-ChildItem Env:を呼び出すとわかります。

TEMP                           C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp
TMP                            C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp

しかし、TeamCityから呼び出されたPowerShellスクリプトから呼び出すと、次のようになります。

TEMP                           C:\TeamCity\buildAgent\temp\buildTmp            
TMP                            C:\TeamCity\buildAgent\temp\buildTmp   

重要な点は、このファイルが認識された後、次のことです。

[15:23:28]: Building target "CoreCompile" completely.
[15:23:28]: Input file "C:\TeamCity\buildAgent\temp\buildTmp\.NETFramework,Version=v4.0.AssemblyAttributes.cs" is newer than output file "obj\Demo\SMM.Data.pdb".

そして、これがプロジェクト全体が再コンパイルされる理由です。

Powershellからスクリプトを実行すると、一時ディレクトリが変更またはクリーンアップされず、ビルドが期待どおりに実行されます。

したがって、このAssemblyAttributesファイルが作成されるディレクトリを変更する方法、またはTeamCityに別のTEMPディレクトリを使用するように指示する方法を知っている人はいますか?これは他の人が遭遇した問題だと私は信じなければなりません。

ありがとう!

4

2 に答える 2

6

したがって、上記の「更新#2」で述べたように、問題は2つの原因で発生しているようです。-TeamCityはTEMPおよびTMP環境変数を独自の一時ディレクトリに設定します-TeamCityはすべてのビルドの前にこの一時ディレクトリを「クリーンアップ」します- msbuildプロセスの一部は、TEMP環境変数で指定されたディレクトリ内の特定のファイルを更新するGenerateTargetFrameworkMonikerAttributeターゲットを実行します。これにより、コンパイラはプロジェクト全体を再コンパイルする必要があります。

これを理解すると、この無関係な質問に適切な答えが見つかりました 。VisualStudio 2010で、.NETFramework、Version = v4.0.AssemblyAttributes.cppファイルが作成されるのはなぜですか。これを無効にできますか?

だから私は追加しました:

<Target Name="GenerateTargetFrameworkMonikerAttribute" />

DLLにコンパイルされ、機能した私のソリューションの両方のプロジェクトに。

于 2011-10-29T01:30:26.260 に答える
0

obliojoeの回答のバリエーションとして、個々のプロジェクトファイルを変更したくない場合、または変更できない場合は、これらのファイルをTEMPフォルダーとの間でバックアップおよび復元できます。

  1. バックアップからファイルを復元する最初の試み:

    copy temp\*.* %%temp%% /y
    echo AssemblyAttributes restore attempted
    
  2. 次に、TeamCityビルドランナーを使用してビルドステップを実行します

  3. ファイルをバックアップします。

    mkdir temp 2> nil
    copy %%temp%%\*AssemblyAttributes.cs temp /y
    echo AssemblyAttributes files saved
    

両方のバッチファイルは同じディレクトリから実行する必要があります。

これらのバッチファイルの最後のECHOに注意してください。これは、正常に終了することを保証するためのものです(エラーコード0)。

于 2017-06-07T07:52:39.517 に答える