私たちのプロジェクトでは、TFSビルドで、すべてのファイルを1つのフラットな構造にドロップするのではなく、各プロジェクトをドロップフォルダーの下の独自のフォルダーに配置する必要があります。説明のために、次のようなものを見たいと思います。
DropFolder/
Foo/
foo.exe
Bar/
bar.dll
Baz
baz.dll
これは基本的に質問と同じ質問です ここ ですが、ワークフローベースのビルドを使用しているため、これらのソリューションは機能していないようです。 CustomizableOutDirプロパティを使用したソリューションは、私たちにとって最適に機能するように見えましたが、そのプロパティを認識させることができません。コマンドライン引数(/ p:CustomizableOutDir = true)としてMSBuildに渡すようにワークフローをカスタマイズしましたが、MSBuildはそれを無視し、ワークフローによって指定されたOutDirに出力を配置しているようです。
ビルドログを確認したところ、CustomizableOutDirプロパティとOutDirプロパティの両方がMSBuildのコマンドライン引数で設定されていることがわかりました。最後にファイルをTeamBuildOutDirにコピーできるように、OutDirを渡す必要があります。
CustomizableOutDirパラメーターが認識されない理由、またはこれを実現するためのより良い方法があるかどうかはわかりませんか?
私はそれを行うための良い方法を考え出しました。 OutDirはワークフロー内で任意に設定できるため、空の文字列に設定すると、MSBuildは代わりにプロジェクト固有のOutputPathを使用することがわかりました。これにより、柔軟性が大幅に向上します。これが私のソリューション全体です(デフォルトのビルドワークフローに基づいています):
Run MSBuildタスクで、OutDirを空の文字列に設定します。同じタスクで、CommandLineArgumentsを次のように設定します。これにより、プロジェクトからTFSのデフォルトのOutDirへの参照を取得できます。
String.Format("/p:CommonOutputPath=""{0}\\""", outputDirectory)
ドロップフォルダにコピーする各プロジェクトで、次のようにOutputPathを設定します。
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath Condition=" '$(CommonOutputPath)'=='' ">bin\Release\</OutputPath>
<OutputPath Condition=" '$(CommonOutputPath)'!='' ">$(CommonOutputPath)YourProjectName\bin\Release\</OutputPath>
</PropertyGroup>
すべてをチェックインすると、各プロジェクトをドロップフォルダーの下の独自のフォルダーにデプロイする作業ビルドができているはずです。
私もこの問題を解決しました。このスレッドの既存のソリューションよりもクリーンだと思います。
Run MSBuild for Project
_アクティビティの前に、Assign
アクティビティを追加しました:projectName = Regex.Replace(New FileInfo(localProject).Name, "\.sln$", "")
。Create Directory
_アクティビティを追加しました:_outputDirectory + "\" + projectName
_OutDir
を_outputDirectory + "\" + projectName
_に変更しました。テンプレートには、エージェント上に構築されている_.sln
_ファイルのフルパス名(例:_c:\build\path\to\MySolution.sln
_)がすでにlocalProject
に入力されています。割り当てアクティビティはパスと内線番号を切り取り、出力をMySolution
に配置します。 projectName
変数を作成し、_System.Text.RegularExpressions
_と_System.IO
_をインポートする必要があります。
OPのソリューションに対する利点は、各_.csproj
_を編集する必要がないことです。その情報は、ソリューションファイルの名前から推測されます。
CSLAシリアル化に同じ名前のSilverlightライブラリと.Netライブラリがあるという問題を回避するために、これを行う必要がありました。ライブラリが上書きされ、テストが失敗します。
Jonathanの答えと Jim Lambの投稿 を使用しましたが、OutDirも空に設定する必要があることがわかりました。
したがって、MSBuildアクティビティに対してこれらのパラメーターを実行する必要があります(次のマクロを使用する場合は、Cleanのアクティビティパラメーターも設定する必要があります。そうしないと、OutputPathが設定されていないという警告が表示されます)。
String.Format("/p:SkipInvalidConfigurations=true;TeamBuildOutDir=""{0}"" {1}", BinariesDirectory, MSBuildArguments)
に設定しますまた、Visual Studioで実行できるマクロを作成しました。このマクロは、構成からOutputPathを削除し、次のようにすべての構成のOutputPathを含むPropertyGroupを追加します。
<PropertyGroup Label="OutputPathLabel">
<OutputPath Condition="'$(TeamBuildOutDir)'=='' ">bin\$(Configuration)\</OutputPath>
<OutputPath Condition="'$(TeamBuildOutDir)'!='' ">$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)\</OutputPath>
</PropertyGroup>
これがマクロです:
Public Sub SetTeamBuildOutDir()
Dim projectObjects = DTE.Solution.Projects
For Each project In projectObjects
If project.ProjectItems IsNot Nothing Then
SetTeamBuildOutDirRecursive(project)
End If
Next
End Sub
Sub SetTeamBuildOutDirRecursive(ByVal proj As Project)
If proj.ConfigurationManager Is Nothing Then
For Each subProj As ProjectItem In proj.ProjectItems
If subProj.SubProject IsNot Nothing Then
SetTeamBuildOutDirRecursive(subProj.SubProject)
End If
Next
Else
SetTeamBuildOutDir(proj)
End If
End Sub
Sub SetTeamBuildOutDir(ByVal project As Project)
'Do not handle .vdproj
If project.FullName.ToLower().EndsWith(".vdproj") Then
Exit Sub
End If
Dim needToSave = False
Dim msproject = ProjectRootElement.Open(project.FullName)
Dim outputPathGroupExists = False
Dim outputPropertyGroup As ProjectPropertyGroupElement = Nothing
Dim lastConfigPropertyGroup As ProjectPropertyGroupElement = Nothing
For Each propertyGroup In msproject.PropertyGroups
If propertyGroup.Label = "OutputPathLabel" Then
outputPathGroupExists = True
outputPropertyGroup = propertyGroup
End If
If Not String.IsNullOrEmpty(propertyGroup.Condition) AndAlso _
propertyGroup.Condition.TrimStart().StartsWith("'$(Configuration)") Then
lastConfigPropertyGroup = propertyGroup
End If
'Remove the OutputPath from the configurations
Dim outputPathElement As ProjectPropertyElement = Nothing
For Each element As ProjectPropertyElement In propertyGroup.Children
If element.Name = "OutputPath" Then
outputPathElement = element
End If
Next
If outputPathElement IsNot Nothing Then
propertyGroup.RemoveChild(outputPathElement)
needToSave = True
End If
Next
'If we want to always remove the group and add it back (in case of modifications to the group)
'If outputPathGroupExists Then
' msproject.RemoveChild(outputPropertyGroup)
' outputPathGroupExists = False
'End If
If Not outputPathGroupExists Then
Dim propertyGroup = msproject.CreatePropertyGroupElement()
propertyGroup.Label = "OutputPathLabel"
'Need to insert the PropertyGroup before the CSharp targets are included
msproject.InsertAfterChild(propertyGroup, lastConfigPropertyGroup)
Dim isDbProject = project.FullName.ToLower().EndsWith(".dbproj")
Dim outputEmpty = propertyGroup.AddProperty("OutputPath", IIf(Not isDbProject, "bin\$(Configuration)\", "sql\$(Configuration)\"))
outputEmpty.Condition = "'$(TeamBuildOutDir)'=='' "
Dim outputTeamBuild = propertyGroup.AddProperty("OutputPath", "$(TeamBuildOutDir)\$(SolutionName)\$(MSBuildProjectName)\$(Configuration)\")
outputTeamBuild.Condition = "'$(TeamBuildOutDir)'!='' "
needToSave = True
End If
If needToSave Then
'checkout the project file with tfs
Shell("C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe checkout " & project.FullName, , True)
'Save the project file
msproject.Save()
End If
End Sub
お役に立てれば!!!
ここでの手順では、プロジェクトファイルを変更する必要はありません http://lajak.wordpress.com/2011/05/07/customize-binaries-folder-in-tfs-team-build/
これは、ソースファイルやプロジェクトファイルを変更する必要のない非常に単純なソリューションです。ビルド定義の[プロセス]-> [ビルドするプロジェクト]を設定するときは、ビルドするプロジェクトで.slnファイルを指定する代わりに、各プロジェクト(.csprojまたは.vbproj)を追加します。ワークフローの「MSBuildforProjectの実行」ステップ内で、OutDirプロパティを次のように変更します。
outputDirectory + "/" + serverBuildProjectItem.Substring(serverBuildProjectItem.LastIndexOf("/"), serverBuildProjectItem.Length - serverBuildProjectItem.LastIndexOf("/")).Replace(".csproj", String.Empty)
これにより、各プロジェクトのビルド出力が、プロジェクトにちなんで名付けられたサブディレクトリに配置されます。
チームビルド2010で最新バージョンのmsbuildを使用できるかどうかはわかりませんが、新しいプロパティ/ p:GenerateProjectSpecificOutputFolder = trueを指定すると、各プロジェクトのビットが$(OutDir)\ $(ProjectName)\にドロップされます。
My Solutionの各実行可能ファイルに対してNugetから パッケージPublishedApplications をインストールし、ビルド中に各プロジェクトの_PublishedApplicationsフォルダーの下にサブフォルダーを作成しました。
TFS/MSBuildで出力ファイルを別々のフォルダーに配置することを試したことがないので、直接答えることはできません。ただし、ここに私があなたのリンクで見つけなかったいくつかの提案があります:
必要なファイルを「デプロイメント」構造にコピーするプロジェクトに、ビルド後の手順を追加できます。 (もちろん、これは開発マシンでも実行されるため、面倒な場合があります)。ライブラリにはこのアプローチを使用します。ライブラリはビルドされてから、他のプロジェクトが参照できるように共有ライブラリ(バイナリ)フォルダーにコピーされます。
MSBuildターゲットを追加して、必要なファイルを必要な場所にコピーできます。デフォルトの「コピーしてドロップフォルダー」ターゲットをオーバーライドして、ファイルを別のフォルダーにコピーし、難読化し、デジタル署名し、インストーラーに組み込み、インストーラーにデジタル署名してからコピーします(およびその他の便利なもの難読化マップファイル)およびドロップフォルダーへの最後のビルド以降の変更のリスト。最終的に、独自のビルド後のターゲットを追加すると、何をどこに配置するかを最大限に制御できます。 (マイナス面として、ビルド後のコピーターゲットに新しいdllまたはexeを手動で追加する必要がある場合があります。これはイライラする可能性があります)
これは、ソースファイルやプロジェクトファイルを変更する必要のない、もう1つの非常に単純なソリューションです。ビルド定義の[プロセス]-> [ビルドするプロジェクト]を設定するときは、ビルドするプロジェクトで.slnファイルを指定する代わりに、各プロジェクト(.csprojまたは.vbproj)を追加します。ワークフローの「MSBuildforProjectの実行」ステップ内で、OutDirプロパティを次のように変更します。
OutputDirectory + "\" + System.IO.Path.GetFileNameWithoutExtension(serverBuildProjectItem)