This is a tip for all developers, not for BuildMasters only.
The issue is those pre and post-build events that developers use to add any conceivable code… especially code that assume a developer’s workstation folder structure.
Such code may break in a TeamBuild for many reasons:
There are some different solutions applicable.
The first one, done by developers on their projects, wrap the code in the pre- or post-build event with a condition, like this:
IF NOT "$(TeamBuildConstants)"=="_TEAM_BUILD_" ( gacutil /i $(TargetFile) /f )
This needs to be done on each project and event but has a very explicit intent; also this is portable to foreseeable versions of Visual Studio and Team Foundation Server.
A second solution is to redefine the CoreBuildDependsOn property via CustomPropertiesForBuild so that PreBuildEvent and PostBuildEvent are left out. Something like this
<PropertyGroup> <CustomPropertiesForBuild> CoreBuildDependsOn= BuildOnlySettings;PrepareForBuild; ResolveReferences;PrepareResources;ResolveKeySource; Compile; UnmanagedUnregistration;GenerateSerializationAssemblies; CreateSatelliteAssemblies;GenerateManifests; GetTargetPath;PrepareForRun;UnmanagedRegistration;IncrementalClean </CustomPropertiesForBuild> </PropertyGroup>
I think of two scenarios where this approach is especially convenient: when you inherit existing code — so called brown field — and need to start control its behavior; or when the build shows weird behavior and you want to troubleshoot its root cause.
Keep in mind that you are touching a reserved property: this may cause problems with Service Packs or new product releases. It is also dangerous if you already use CustomPropertiesForBuild — could be hard to track what happens in the build.
I suggest to use this approach as last resort and for a limited time.
A third solution, requiring a bit more effort, is to rewrite the action as an MSBuild task and leverage the BeforeBuild and AfterBuild targets with an apt condition, like:
<Target Name="AfterBuild" Condition="'$(TeamBuildConstants)'!='_TEAM_BUILD_'> <GacUtil Command="Install" Assemblies="$(TargetFile)" Force="true" /> </Target>
using the MSBuild Community Tasks or, using the MSBuild Extension Pack:
<Target Name="AfterBuild" Condition="'$(TeamBuildConstants)'!='_TEAM_BUILD_'> <Gac TaskAction="AddAssembly" AssemblyPath="$(TargetFile)" Force="true" /> </Target>
As there are lot of built-in and publicly available tasks, this could be an elegant and viable approach.
UPDATE: the above suggestion works for Visual Studio + Team Foundation Server 2008.
In Visual Studio 2010 and later, the recommended method is to use the predefined property BuildingInsideVisualStudio
IF "$(BuildingInsideVisualStudio)"=="true" ( …your code here… )
Hope this helps.