Working with multiple team projects in Team Build
Building solutions that reference to assemblies belonging to different team project
Scenario
Assume that we two projects (ConsoleApplication1 and ConsoleApplication2) under team project (TP1) and they are using the assembly (commonlibrary.dll) that is checked in under a different team project (TP2). Let us assume the corresponding paths under version control are
$/TP1/Framework/Common/v2.0/commonlibrary.dll
$/TP2/Main/ConsoleApplication1/ConsoleApplication1.sln
$/TP2/Main/ConsoleApplication1/ConsoleApplication1.sln
Note: please make sure that you have used File Reference to add the reference for commonlibrary.dll and CopyLocal option is set to true. Otherwise your desktop build scenario will be broken.
Custom steps to enable building the project
- Create the BuiltType “Type1” for TP2.
- Check out the Tfsbuild.proj file for “Type1” build type.
- Reset the following property. This is done to skip invoking the default tasks to delete and recreate workspace on the build machine.
<SkipInitializeWorkspace>true</SkipInitializeWorkspace>
- Define the new property. This is just for the user convenience and will be used in the custom target “BeforeGet” (mentioned below)
<TfCommand>$(TeamBuildRefPath)\..\tf.exe</TfCommand>
- Define the folder mappings item group. (You are responsible for giving the correct local paths for the build machine. Please note that multiple mappings can not share the same local folder and will result in MappingConflictException in the CreateWorkspace task. Another recommendation is to avoid mapping to $(SolutionRoot). This is because if while creating workspace, task detects overlapping local paths, it will try to merge the local paths and screw up the relative paths. Please note that I have not explored the cloaking option.
<ItemGroup>
<Map Include="$/TP2/Main">
<LocalPath>$(SolutionRoot)\Main</LocalPath>
</Map>
<Map Include="$/TP1/Framework">
<LocalPath>$(SolutionRoot)\Framework</LocalPath>
</Map>
</ItemGroup>
- Override the “BeforeGet” target.
<Target Name="BeforeGet">
<!— to remove any workspace that exist with the same name, from some previous build à
<DeleteWorkspaceTask
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
Name="$(WorkspaceName)" />
<!— create the workspace with default mapping that maps $(SolutionRoot) to $/ à
<Exec
WorkingDirectory="$(SolutionRoot)"
Command=""$(TfCommand)" workspace /new $(WorkspaceName) /server:$(TeamFoundationServerUrl)"/>
<!— task will add the folder mappings corresponding to items define in step 5 à
<Exec
WorkingDirectory="$(SolutionRoot)"
Command=""$(TfCommand)" workfold /map /workspace:$(WorkSpaceName) /server:$(TeamFoundationServerUrl) "%(Map.Identity)" "%(Map.LocalPath)""/>
<!— remove the default mapping ( $(SolutionRoot) ß> $/)that was created initially. Otherwise all the team projects will be synced under the $(SolutionRoot) à
<Exec
WorkingDirectory="$(SolutionRoot)"
Command=""$(TfCommand)" workfold /unmap /workspace:$(WorkSpaceName) "$(SolutionRoot)""/>
</Target>
- Verify that sln paths (SolutionToBuild itemgroup) for correct relative paths
<SolutionToBuild Include="$(SolutionRoot)\Main\ConsoleApplication1\ConsoleApplication1.sln" />
<SolutionToBuild Include="$(SolutionRoot)\Main\ConsoleApplication2\ConsoleApplication2.sln" />
- Similarly verify the vsmdi paths (MetaDataFile itemgroup) for correct relative paths.
- Checkin the tfsbuild.proj file and launch the build.
Recommendations
- Please make sure that CopyLocal option is set for the file reference.
- Use File reference to add references for assemblies belonging to different team projects. Sometime these reference paths will be broken because the relative path on the build machine is different from the one mentioned in the csproj file of your project. In such cases you need to specify the correct location of the external assembly. You can easily do it by defining “AdditionalReferencePath” item pointing to the folder containing the assembly.
- Please try to avoid mapping directly to “$(SolutionRoot)”. Still if your “Map” item group contains any working folder mapping that points to only “$(SolutionRoot)”, then you need to remove the following line from the BeforeGet target :-
<Exec Command=""$(TfCommand)" workfold /unmap /workspace:$(WorkSpaceName) "$(SolutionRoot)"" WorkingDirectory="$(SolutionRoot)"/>
References
Other interesting posts on the related/same issue are [post] [post1] [post2] [post3]
Comments
Anonymous
February 01, 2006
Great post!
I’m having a problem in how to get my test cases to run after running a build. Here’s what I’m trying to do:
Project
|--Dev
|--Site
|--UnitTests
|--Docs
|--Tools
|--Test
|--Automations
|--Docs
|--TRD
|--Spec
We need to build the Site, and run the Automations in the Test folder, but don’t want to load everything under Project, so we’re trying to selectively include the sections we want.
As such, I want to include the following Map node in my Build .proj file
<Map Include="$/Project/Main/Dev/Site">
<LocalPath>$(SolutionRoot)Site</LocalPath>
</Map>
<Map Include="$/Project/Main/Test">
<LocalPath>$(SolutionRoot)Test</LocalPath>
</Map>
However, doing this causes me to get a OutOfMemoryException after about 5 minutes of the build server trying to get sources. Even when I get rid of the second map element, this happens. In fact, any time I map LocalPath to anything other than “$(SolutionRoot)”, I get the exception. I notice that you have mapped successfully to $(SolutionRoot)Main, do you know why I would be seeing the problems I'm seeing? Thank you very much!
-JeffAnonymous
February 01, 2006
Sorry, the above folder structure should show "Project" as highest level. Dev, Test, and Docs should be second level, and everything else is third level.
Project
|--Dev
|---|--Site
|---|--UnitTests
|---|--Docs
|---|--Tools
|--Test
|---|--Automations
|--Docs
|---|--TRD
|---|--SpecAnonymous
February 01, 2006
Jeff,
It looks like you are interested in selectively sync specific folders and not download everything. Moreover I am assuming everything in under same team project. Please check the post for the solution -
http://blogs.msdn.com/manishagarwal/archive/2005/10/13/480584.aspx
Hope it helpsAnonymous
February 03, 2006
I'm afraid this didn't work, at least not what I expected it to do. For example, i added the item
<InternalMapping ServerItem="$/Project/Site/Main/Docs" Type="Cloak"/>
Then I checked the sources folder in the build location, and the docs folder was still there, as it was previously. My goal is simply to keep from 'getting' folders that arn't necessary for this build, such as the Docs folder. Am I doing something wrong? Thanks for the help!Anonymous
April 05, 2006
http://blogs.msdn.com/manishagarwal/archive/2005/12/22/506635.aspxAnonymous
May 20, 2006
One of the challenges we hadn&rsquo;t figured out was how to deal with the case where Team Project B...Anonymous
July 20, 2006
Swap the map and unmap elements in BeforeGet and it works.
See:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=367208&SiteID=1Anonymous
August 29, 2006
Last week, the folks at Vertigo Software wrote a couple of really good posts involving Team Build.
The...Anonymous
March 10, 2007
Hi Al I have a situation where the reverse order of team projects needs to be compiled in a team build. How do i specify the path for the source project for team project 1 in custom task?Anonymous
March 17, 2007
I returned to work after Tuesday's MSDN Roadshow fired up and full of ideas, eager to try out ASP.NETAnonymous
April 02, 2008
Which idiot came up with this? http://msdn2.microsoft.com/en-us/library/bb668986.aspx You end up with a folder structure 5 levels deep before you get to any files. And you've got folders named things like 'MyWebAppSln' - why not 'MyWebApplication'? Sorry if this is the wrong place to vent, but the article links to this blog post.Anonymous
September 03, 2008
The solution structure described on MSDN works quite well. The names don't matter too much, but the structure copes with 90% of development.Anonymous
October 01, 2008
PingBack from http://doddychsaputra.thecoderblogs.com/2008/10/02/how-to-structure-aspnet-applications-in-visual-studio-team-foundation-server/Anonymous
October 01, 2008
PingBack from http://doddychsaputra.thecoderblogs.com/2008/10/02/how-to-structure-windows-applications-in-visual-studio-team-foundation-server-team-foundation-server/Anonymous
December 10, 2008
Building solutions that reference to assemblies belonging to different team project If you facing theAnonymous
February 02, 2009
Huaahhh… ini kasus yang umum namun anehnya agak perlu sedikit effort untuk bisa berhasil. Kasus apa sihAnonymous
June 17, 2009
I am working with several team projects that need assemblies from other team projects. For example,...Anonymous
December 10, 2011
The comment has been removed