Tuesday, June 10, 2008

Detecting TFS Server version from 2008 client

With the release of VSTS 2008, in certain configurations you might want to detect what version of the server your client runs against, the important configuration being 2008 client vs. 2005 TFS server, since in that configuration the feature-set on the client will be more restrictive (2005 client against 2008 server is no problem as it will not use any new features anyway).

It turns out that to get this bit of information your best bet is to use Team Build object model (the advise is courtesy of Aaron Hallberg):

IBuildServer buildServer = 
    teamFoundationServer.GetService(typeof(IBuildServer)) 
     as IBuildServer;
if (buildServer.BuildServerVersion ==  BuildServerVersion.V1)
    ; // server is 2005
else if (buildServer.BuildServerVersion == BuildServerVersion.V2)
    ; // server is 2008

If you think about it for a second, it sort of makes sense, since Team Build is the component that differs most between TFS 2005 and 2008 versions. So in the absence of general service versioning model one can use that for determining the server version.

And if you did not know it yet, Team Build object model was greatly enhanced in 2008. One of the recent discoveries for me was the custom properties bag available for builds build types in Team Build 2008 (as described in Aaron Hallberg’s blog). Using the custom properties one could provide custom categories for build types(and perhaps even expose them in Team Explorer). This is something I am planning to take a stab on (if time allows).

For Team Build OM intro there is a detailed post by Martin Woodward (it even has class diagram drawing!); and you can download the whole documentation here.

Updated: Unfortunately, it appears that custom properties I was so enthusiastic about are available for builds only, not for the build types. Thanks to Ed for correction!

Tuesday, January 29, 2008

Skipping post-build in VS project in Team Build

Interesting question has come up in the forums: "If one has custom pre- or post- build logic in Visual Studio projects, that are being built both on desktop and using Team Build, how one would disable the pre-/post-build for non-desktop build?".
Or to be more concise - is there any property available that makes it possible to detect, whether the build is being performed from Visual Studio or from Team Build process?

Now, Team Build build types will simply call MSBuild task with the solution(s) to build; will Team Build pass any custom properties to MSBuild with the solution files?

It turns out that Team Build does indeed pass such property, named TeamBuildConstants; thus when the solution will be built from the Team Build script, the property will get the value of _TEAM_BUILD_, as defined in Microsoft.TeamFoundation.Build.targets file.

Then Visual Studio project (C# and VB.NET alike) can be modified in the following manner:


<!-- Prebuild logic will be executed both in VS and Team Build compilations -->
<Target Name="BeforeBuild">
    <Exec Command="attrib -r $(TargetPath)"/>
</Target>

<!-- Postbuild logic that will not be executed in Team Build-->
<Target Name="AfterBuild" Condition="'$(TeamBuildConstants)' == ''">
    <Copy SourceFiles="$(TargetPath)"
      DestinationFolder="$(SolutionDir)\bin\$(ConfigurationName)" />
</Target>

Team Build targets file also exposes property with very tempting name - SkipPostBuild; however, modifying the property value in TFSBuild.proj will have no effect on the projects post build logic. Setting SkipPostBuild property to false disables running GenCheckinNotesUpdateWorkItems task during Team Build build, and thus has no connection to Visual Studio projects logic.