If you are using
Team Foundation Server as your SCM tool, I hope you're taking advantage of using the
Team Build tool to create re-producable public builds for your projects. Very cool, and very useful, especially for those Enterprise applications. As you use Team Build you'll need to make changes to how your build process is executed. You can make the customizations in the
TFSBuild.proj file. This is the file that will drive your team build. In this file there are many properties declared that are generated by the New Build Type Creation Wizard. These properties are contained in the first
PropertyGroup element in that file. Some of these properties include; Description, DropLocation,BuildDirectoryPath,... which are used internally by Team Build to setup the build. Of course Team Build uses MSBuild to actually execute the build, but some things need to happen before/after MSBuild gets involved. For instance creating the Build report, which require those values. In the ideal world you'd expect for those values to be gathered using the
MSBuild Object Model, but this is not the case. Team Build is extracting those values as they are declared.
There has been a few posts about this particular problem on the
MSBuild MSDN Forum. Those posts are at:
Post: Property Evaluation Order (beta 3)
Properties in properties
In the post Property Evaluation Order (beta 3) I provide a workaround for most situations, but its not always perfect. Here it is for you to see:
It seems like Team
build is not using the msbuild object model to get those evaluated
properties, but instead are simply extracting the text value from those
property declarations.
I tried to overwirte it in different places in the project file as
well, with no luck. It always took the first declaration. I'm guessing
that the property is not able to be overwritten because it is passed in
as a command line parameter to msbuild.exe by team build. But there is
a workaround that solves some of the issues. In your TFSBuild.proj
file, modify the DropLocation to one that doesn't use any properties
and insert the following towards the bottom:
<PropertyGroup>
<RootProjectFolder>ProjectX</RootProjectFolder>
<DropBuildDependsOn>
FixDropLocation;
$(DropBuildDependsOn);
</DropBuildDependsOn>
</PropertyGroup>
<Target Name="FixDropLocation">
<CreateProperty Value="$(DropLocation)\$(RootProjectFolder)">
<Output TaskParameter="Value" PropertyName="DropLocation"/>
</CreateProperty>
<Message Text="Drop loc: $(DropLocation)" Importance="high"/>
</Target>
This prepends the FixDropLocation to the DropBuildDependsOn list of targets, so it will be executed before the DropBuild target.
This cause your project drop files to be dropped in the location tat
you want. This is able to overwrite the DropLocation property becuase
we are using the CreateProperty task to overwrite this instead of the normal property declaration.
This is not however a perfect solution, because your build log will always be located in the DropLocation
that was originally declared (the one w/o the property embedded within
it). And in the Team build type history the drop location will also
have this location as well. But it does place the files where you want
them :)
Unfortunately it looks like the DropLocation that is given to TFS is
happening outside the scope of MSBuild so I'm not sure you have a lot
of options. You can't even pass this as a command line parameter to the
tfsbuild.exe utility either. Let me know if this is not clear.
Sayed Ibrahim Hashimi