<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Team Build</title>
        <link>http://geekswithblogs.net/jakob/category/9658.aspx</link>
        <description>Team Build</description>
        <language>en-US</language>
        <copyright>Jakob Ehn</copyright>
        <managingEditor>jakob.ehn@inmeta.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Handling Warnings and Errors with InvokeProcess in TFS 2010 Build</title>
            <link>http://geekswithblogs.net/jakob/archive/2012/02/01/handling-warnings-and-errors-with-invokeprocess-in-tfs-2010-build.aspx</link>
            <description>&lt;p&gt;   &lt;br /&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.workflow.activities.invokeprocess.aspx" target="_blank"&gt;InvokeProcess activity&lt;/a&gt; is very useful when it comes to running shell commands and external command line tools during a build process. When it comes to integrating with TFS source control during a build, the TF.exe command line tool can be your friend, as it lets you do most of the usual stuff such as check-in, checkout, add, modify workspaces etc.&lt;/p&gt;  &lt;p&gt;However, it can be a bit tricky to handle the output from tf.exe, since it often produces warnings that is not necessarily a problem for your build. This is not a problem related only to tf.exe, but to all applications that produces errors and warnings on the canonical error format.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The normal way to use the InvokeProcess activity is to setup the necessary parameters to call the tool with the correct path, working directory and command line switches. Then you add a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.workflow.activities.writebuildmessage.aspx" target="_blank"&gt;WriteBuildMessage&lt;/a&gt; activity to the Handle Standard Output action handler and a &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.build.workflow.activities.writebuilderror.aspx" target="_blank"&gt;WriteBuildError&lt;/a&gt; to the Handle Error Output action handler. In addition, you store the Result output property from the InvokeProcess activity in a workflow variable that you can evaluate after the InvokeProcess activity has finished.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_thumb.png" width="273" height="272" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;This will output all standard output from the application to the build log, and all errors will be written as errors to the build log and will partially fail the build.    &lt;br /&gt;If you try this with TF.exe you will probably notice a problem with warnings from the tool being reported as errors in the build, causing it to partially fail the build, even though the ReturnCode was zero.     &lt;br /&gt;    &lt;br /&gt;To solve this problem you need to collect the information that is passed to the Error Output action handler. Note that this handler is called several times so you need to handle formatting of the output in some way. Then, you check the ReturnCode from the InvokeProcess activity and in case this is &amp;lt;&amp;gt; 0, you write the collection information as an error to the build log (using WriteBuildError) and then throw an exception. Otherwise, just write the information to the build log using WriteBuildMessage, so you get all information out there.&lt;/p&gt;  &lt;p&gt;The finished sample looks like this:    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_4.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_thumb_1.png" width="451" height="609" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;   &lt;br /&gt;In the "Check out files” sequence I have defined a workflow variable called ErrorOutputFromTF of type string. In the “Handle Error Output” handler, I append the error to this variable, using the Assign activity:     &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_thumb_2.png" width="461" height="202" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;   &lt;br /&gt;I just append a newline character at the end to have all the errors on separate rows in the build log later. After the InvokeProcess activity I check the TFExitCode variable,  that was assigned the ResultCode value from the InvokeProcess activity previously, if it is &amp;lt;&amp;gt; 0 I write the ErrorOutputFromTF to the build error log and then I throw an exception. &lt;/p&gt;  &lt;p&gt;Here is a sample build log output:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_8.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Handling-Errors-from-TF.exe_774E/image_thumb_3.png" width="874" height="416" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Note that tf.exe in this case outputs information about check-in policies that have been overridden. This is an example of information that would cause the build to partially fail, but is now logged as information.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/148552.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2012/02/01/handling-warnings-and-errors-with-invokeprocess-in-tfs-2010-build.aspx</guid>
            <pubDate>Wed, 01 Feb 2012 19:55:18 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/148552.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2012/02/01/handling-warnings-and-errors-with-invokeprocess-in-tfs-2010-build.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/148552.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/148552.aspx</trackback:ping>
        </item>
        <item>
            <title>Introducing: Community TFS Build Manager</title>
            <link>http://geekswithblogs.net/jakob/archive/2011/12/30/introducing-community-tfs-build-manager.aspx</link>
            <description>&lt;p&gt;The latest release of the &lt;a href="http://tfsbuildextensions.codeplex.com/" target="_blank"&gt;Community TFS Build Extensions&lt;/a&gt; include a brand new tool called &lt;em&gt;Community TFS Build Manager&lt;/em&gt; and has been created for two reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;An implementation of the Team Foundation Build API which is referenced by the Rangers Build Customization Guidance V2 (available H1 2012)      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Provide a solution to a real problem. The Community TFS Build Manager is intended to ease the management of builds in medium to large Team Foundation Server environments, though it does provide a few features which all users may find useful.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;   &lt;br /&gt;The first version of the tool has been implemented by myself and &lt;a href="http://www.freetodev.com/" target="_blank"&gt;Mike Fourie&lt;/a&gt;. You can download the extension from the Visual Studio Gallery here:    &lt;br /&gt;&lt;a title="http://visualstudiogallery.msdn.microsoft.com/16bafc63-0f20-4cc3-8b67-4e25d150102c" href="http://visualstudiogallery.msdn.microsoft.com/16bafc63-0f20-4cc3-8b67-4e25d150102c"&gt;http://visualstudiogallery.msdn.microsoft.com/16bafc63-0f20-4cc3-8b67-4e25d150102c&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;     &lt;br /&gt;Note 1:&lt;/strong&gt; The full source is available at the Community TFS Build Extension site&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note 2:&lt;/strong&gt; The tool is still considered alpha, so you should be a bit careful when running commands that modify or delete information in live environments, e.g. try it out first in a non-critical environment.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note 3&lt;/strong&gt;: The tool is also available as a stand alone WPF application. To use it, you need to download the source from the CodePlex site and build it. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You can either install the extension from the above link, or just open the Visual Studio Extension Manager and go to the Online gallery and search for TFS Build:   &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_26.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_12.png" width="960" height="514" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;After installing the build manager, you can start it either from the Tools menu or from the Team Explorer by right-clicking on the Builds node on any team project:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_2.png" width="448" height="321" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;This will bring up a new tool window that will by default show all build definition in the currently selected team project. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;     &lt;br /&gt;View and sort Builds and Build Definitions across multiple Build Controllers and Team Projects       &lt;br /&gt;&lt;/strong&gt;This has always been a major limitation when working with builds in Team Explorer, they are always scoped to a team project. It is particularly annoying when viewing queued builds and you     &lt;br /&gt;have no idea what other builds are running on the same controller. In the TFS Build Manager, you can filter on one/all build controllers and one/all team projects:    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb.png" width="1185" height="191" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The same filters apply when you switch between Build Definitions and Builds. In the following screen shot, you can see that three builds from three different team projects are running on the same controller:    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_1.png" width="1191" height="201" /&gt;&lt;/a&gt;    &lt;br /&gt;    &lt;br /&gt;You can easily filter on specific team projects and/or build controllers. Note that all columns are sortable, just click on the header column to sort it ascending or descending.     &lt;br /&gt;This makes it easy to for example locate all build definitions that use a particular build process template, or group builds by team project etc.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bulk operations on Build Definitions&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The main functionality that this tool brings in addition to what Team Explorer already offers, is the ability to perform bulk operations on multiple build definitions/builds. Often you need to modify or    &lt;br /&gt;delete several build definitions in TFS and there is no way to do this in Team Explorer. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;In the TFS Build Manager, just select one or more builds or build definitions in the grid and right-click. The following context menu will be shown for build definitions:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_3.png" width="273" height="179" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Change Build Process Templates &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This command lets you change the build process template for one or more build definitions. It will show a dialog with all existing build process templates in the corresponding team projects:   &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_4.png" width="705" height="403" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Queue&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This will queue a “default” build for the the selected build definitions. This means that they will be queued with the default parameters.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Enable/Disable&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Enables or disables the selected build definitions. Note that disabled build definitions are by default now shown. To view disabled build definitions, check the &lt;em&gt;Include Disabled Builds&lt;/em&gt; checkbox:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_12.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_5.png" width="361" height="74" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Delete&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This lets you delete one ore more build definitions in a single click. In Team Explorer this is not possible, you must first delete all builds and then delete the build definition. Annoying! &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/wlEmoticon-smile_2.png" /&gt;&lt;/p&gt;  &lt;p&gt;TFS Build Manager will prompt you with the same delete options as in Team Explorer, so no functionality is lost:   &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_14.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_6.png" width="562" height="407" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Set Retention Policies &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Allows you to set retentions policies to several build definitions in one go. Note that only retention policies for Triggered and Manual build definitions can be updated, not private builds.  &lt;br /&gt;This feature also gives you the same options as in Team Explorer:    &lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_16.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_7.png" width="531" height="260" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Clone to Branch&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;My favorite feature &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/wlEmoticon-smile_2.png" /&gt; Often the reason for cloning a build definition is that you have created a new source code branch and now you want to setup a matching set of builds for the new branch. When using the Clone build definition feature of the TFS Power Tools, you must update several of the parameters of the build definition after, including:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Name &lt;/li&gt;    &lt;li&gt;Workspace mappings &lt;/li&gt;    &lt;li&gt;Source control path to Items to builds (solutions and/or projects) &lt;/li&gt;    &lt;li&gt;Source control path to test settings file &lt;/li&gt;    &lt;li&gt;Drop location &lt;/li&gt;    &lt;li&gt;Source control path to TFSBuild.proj for UpgradeTemplate builds&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;   &lt;br /&gt;All this is done automagically when using the Clone to Branch feature! When you select this command, the build manager will look at the Items to build path (e.g. solution/projects) and find all child branches to this path and display them in a dialog:    &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_18.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_8.png" width="500" height="300" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;When select one of the target branches, the new name will default to the source build definition with the target branch name appended. Of course you can modify the name in the dialog. After pressing OK, a new build definition will be created and all the parameters listed above will be modified accordingly to the new branch.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bulk operations on Builds&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You can also perform several actions on builds, and more will be added shortly. In the first release, the following features are available:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Delete&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This will delete all artifacts of the build (details, drops, test results etc..). It should show the same dialog as the Delete Build Definition command, but currently it will delete everything. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Open Drop Folders&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Allows you to open the drop folder for one or more builds&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Retain Indefinitely&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Set one or more builds to be retained indefinitely.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bonus Feature – Generate DGML for your build environment&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This feature was outside spec, but since I was playing around with generating DGML it was easy to implement this feature and it is actually rather useful. It quickly gives you an overview of your build resources, e.g. which build controllers and build agents that exist for the current project collection, and on what hosts they are running. The command is available in the small toolbar at the top, next to the refresh button:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_24.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_11.png" width="231" height="109" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Here is an example from our lab environment:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_22.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Introducing-Community-TFS-Build-Manager_14F14/image_thumb_10.png" width="1222" height="234" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The dark green boxes are the host machine names and the controller and agents are contained within them.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Currently the only way to view DGML files are with Visual Studio 2010 Premium and Ultimate. &lt;/p&gt;    &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I hope that many of you will find this tool useful, please report issues/feature requests to the Community TFS Build Extensions CodePlex site! &lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/148173.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2011/12/30/introducing-community-tfs-build-manager.aspx</guid>
            <pubDate>Fri, 30 Dec 2011 11:36:06 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/148173.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2011/12/30/introducing-community-tfs-build-manager.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/148173.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/148173.aspx</trackback:ping>
        </item>
        <item>
            <title>TF237165: Team Foundation could not update the work item because of a validation error on the server.</title>
            <link>http://geekswithblogs.net/jakob/archive/2011/12/12/tf237165-team-foundation-could-not-update-the-work-item-because.aspx</link>
            <description>&lt;p&gt;I often use the VS 2010/TFS 2010 evaluation virtual machines that Microsoft publishes every 6 months with the latest bits. It’s a great timesaver to use an image where everything is already setup and also contains a bit of sample data that is useful when you want to demo something for customers. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;There is one thing that has always been a, albeit small, but still very annoying problem and that is that the builds always partially fail when you start using the image. When you want to demo the powerful feature of associated work items in a build, you’ll find yourself with your pants down since the build fails when trying to update the associated work item! Even when looking at the historical builds for the Tailspin Toys project, you will notice that they also partially failed:&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_thumb.png" width="1254" height="175" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;If you look at the error message in the build details, you’ll see the following error:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_thumb_1.png" width="1274" height="95" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;The work item 'XX' could not be updated: 'TF237165: Team Foundation could not update the work item because of a validation error on the server. This may happen because the work item type has been modified or destroyed, or you do not have permission to update the work item.'&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;The problem here is that the build agent by default is running as the NT AUTHORITY\SYSTEM account, which is an account that do not have permission to modify work items. Your best option here is to switch account and use the Network Service account instead. Open TFS Administration Console, and select the Build Configuration node. Press the Stop link in the Build Service section:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_thumb_3.png" width="1065" height="193" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Select Properties and select NT AUTHORITY\NetworkService as Credentials&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_thumb_2.png" width="403" height="470" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Press Start to start the build service with the new credentials.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;If you would queue a new build now, the build would fail because of conflicting workspace mappings. The reason for this is that we haven’t changed the working folder path for the build agents, so when the build agent try to create a new workspace, the local path will conflict with the workspace previously created by NT AUTHORITY\SYSTEM.&lt;/p&gt;  &lt;p&gt;So to resolve this we can do two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;(Preferred). Delete the team build workspaces previously created by the SYSTEM account. To do this, start a Visual Studio command prompt and type:     &lt;br /&gt;      &lt;br /&gt;&lt;strong&gt;tf.exe workspace /delete &amp;lt;workspacename&amp;gt;;NT AUTHORITY\SYSTEM       &lt;br /&gt;        &lt;br /&gt;&lt;/strong&gt;      &lt;br /&gt;If you need to list the workspaces to get the names, you can type:      &lt;br /&gt;      &lt;br /&gt;&lt;strong&gt;tf workspaces /owner:NT AUTHORITY\SYSTEM /computer: &amp;lt;buildserver&amp;gt;       &lt;br /&gt;        &lt;br /&gt;&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;(Less preferred, but good if you want to switch back later to the old build service account)  &lt;br /&gt;      &lt;br /&gt;You can also modify the working folder path for the build agents, so that they don’t conflict with the existing workspaces. Click Properties on the build agent(s) and modify the Working Directory proprerty:      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_10.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TF237165-Team-Foundation-could-not-upda_83C6/image_thumb_4.png" width="490" height="450" /&gt;&lt;/a&gt;b      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;In this case, you can for example change it to &lt;em&gt;&lt;strong&gt;$(SystemDrive)\Builds\NS\$(BuildAgentId)$(BuildDefinitionPath)&lt;/strong&gt;&lt;/em&gt;  where NS = Network Service.       &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/148013.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2011/12/12/tf237165-team-foundation-could-not-update-the-work-item-because.aspx</guid>
            <pubDate>Mon, 12 Dec 2011 16:21:15 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/148013.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2011/12/12/tf237165-team-foundation-could-not-update-the-work-item-because.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/148013.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/148013.aspx</trackback:ping>
        </item>
        <item>
            <title>TFS 2010 Build - Troubleshooting the TF215097 error</title>
            <link>http://geekswithblogs.net/jakob/archive/2011/12/08/tfs-2010-build---troubleshooting-the-tf215097-error.aspx</link>
            <description>&lt;p&gt;Anyone working with developing custom activities in TFS 2010 Build has run into the following dreadful error message when running the build:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TF215097: An error occurred while initializing a build for build definition \TeamProject\MyBuildDefinition: Cannot create unknown type '{clr-namespace:[namespace];assembly=[assembly]}Activity &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;What the error means is that when the TFS build service loads the build process template XAML for the build definition, it can’t create an instance of the customer workflow activity that is referenced from it.&lt;/p&gt;  &lt;p&gt;The problem here is that there are several steps that all need to be done correctly for this process to work. &lt;/p&gt;  &lt;p&gt;Make sure that:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When developing custom workflow, you keep the XAML builds template workflows in one project, and the custom activities in another project. The template workflow project shall reference the custom activities project.     &lt;br /&gt;This setup also makes sure that your custom activities show up in the toolbox when designing your workflow.      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;You have checked in the modified version of the XAML workflow (easy to forget)     &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Your custom activity has the the &lt;strong&gt;BuildActivityAttribute&lt;/strong&gt;:      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/2ea22155b985_DADF/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/2ea22155b985_DADF/image_thumb_1.png" width="562" height="63" /&gt;&lt;/a&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Your custom activity is &lt;strong&gt;public &lt;/strong&gt;(common mistake…)      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;You have configured your build controller with the path in source control where the custom activities are located      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/2ea22155b985_DADF/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/2ea22155b985_DADF/image_thumb_2.png" width="519" height="132" /&gt;&lt;/a&gt;      &lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Verify that all dependencies for the custom activity assembly/assemblies have been checked into the same location as the assembly     &lt;br /&gt;&lt;strong&gt;NB&lt;/strong&gt;: You don’t need to check in TFS assemblies and other references that you know will be in the GAC on the build servers.      &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;The reference to the custom activity assembly in the XAML workflow is correct:&lt;/li&gt;    &lt;pre style="font-family: ; background: white; color: "&gt;&lt;font face="Consolas"&gt;&lt;span style="color: "&gt;&lt;font color="#ff0000"&gt;&lt;font style="font-size: 9.8pt"&gt;xmlns:obc&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;font style="font-size: 9.8pt"&gt;&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;/span&gt;"&lt;span style="color: "&gt;&lt;font color="#0000ff"&gt;clr-namespace:Inmeta.Build.CustomActivities;assembly=Inmeta.Build.CustomActivities&lt;/font&gt;&lt;/span&gt;"
&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/ul&gt;

&lt;p&gt;
  &lt;br /&gt;But, even if you have all these step done right, you can still get the error. I had this problem recently when working with the code metrics activities for the &lt;a title="http://tfsbuildextensions.codeplex.com/" href="http://tfsbuildextensions.codeplex.com/"&gt;http://tfsbuildextensions.codeplex.com/&lt;/a&gt; community project. 

  &lt;br /&gt;

  &lt;br /&gt;The thing that saved me that time was the &lt;strong&gt;Team Foundation Build Service Events &lt;/strong&gt;eventlog. This is a somewhat hidden “feature” that is very useful when troubleshooting build problems. You find it under Custom View

  &lt;br /&gt;in the event log on the build servers&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/2ea22155b985_DADF/image_2.png"&gt;&lt;img style="display: inline" title="image" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/2ea22155b985_DADF/image_thumb.png" width="296" height="245" /&gt;&lt;/a&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;In this case I had the following message there:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Service 'LT-JAKOB2010 - Agent1' had an exception: 
      &lt;br /&gt;Exception Message: Problem with loading custom assemblies: Method 'get_BuildAgentUri' in type 'TfsBuildExtensions.Activities.Tests.MockIBuildDetail' from assembly 'TfsBuildExtensions.Activities.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation. (type Exception)&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Which made me realize that I had by accident checked in one of the test assemblies into the custom activity source control folder in TFS. &lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Unfortunately this whole process with developing you own custom activities is problematic and error prone, hopefully this will be better in future versions of TFS. Once you have your setup working however, changing and adding new custom activities is easy. And deployment is a breeze thanks to the automatic downloading and recycling of build agents that the build controller handles.

  &lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/147983.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2011/12/08/tfs-2010-build---troubleshooting-the-tf215097-error.aspx</guid>
            <pubDate>Thu, 08 Dec 2011 19:51:48 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/147983.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2011/12/08/tfs-2010-build---troubleshooting-the-tf215097-error.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/147983.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/147983.aspx</trackback:ping>
        </item>
        <item>
            <title>First stable release of the Community TFS 2010 Build Extensions</title>
            <link>http://geekswithblogs.net/jakob/archive/2011/07/04/first-stable-release-of-the-community-tfs-2010-build-extensions.aspx</link>
            <description>&lt;p&gt;Today the first stable release of the &lt;a href="http://tfsbuildextensions.codeplex.com/" target="_blank"&gt;Community TFS 2010 Build Extensions&lt;/a&gt; shipped on the CodePlex site. Visual Studio ALM MVP &lt;a href="http://freetodev.com/" target="_blank"&gt;Mike Fourie&lt;/a&gt; (aka Mr &lt;a href="http://msbuildextensionpack.codeplex.com/" target="_blank"&gt;MSBuild Extension Pack&lt;/a&gt;) has been the leader of this project and has done a tremendous job, both in contributing functionality as well as coordinating the work for the first release. Great work Mike! I (as well as several others) have contributed a small part of the activities, I plan to be working on the upcoming releases as well. &lt;/p&gt;  &lt;p&gt;The build extensions contain approximately 100 custom activities that covers several different areas, such as IIS7, Hyper-V, StyleCop, NUnit, Powershell etc, as well as some core functionality (Assembly versionig, file management, compression, email etc etc). In addition to more activities in upcoming releases, the plan is to include build process templates for different scenarios.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Please download the release and try it out, and give us feedback! &lt;/p&gt;  &lt;p&gt;To give you a hint of the content, here is a class diagram that shows the content of the “Core” activities project (there are several other projects included as well):&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/First-release-of-the-Community-Build-Ext_13733/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/First-release-of-the-Community-Build-Ext_13733/image_thumb.png" width="1489" height="363" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/146075.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2011/07/04/first-stable-release-of-the-community-tfs-2010-build-extensions.aspx</guid>
            <pubDate>Mon, 04 Jul 2011 20:50:15 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/146075.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2011/07/04/first-stable-release-of-the-community-tfs-2010-build-extensions.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/146075.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/146075.aspx</trackback:ping>
        </item>
        <item>
            <title>TFS 2010 Inmeta Build Explorer</title>
            <link>http://geekswithblogs.net/jakob/archive/2011/04/04/tfs-2010-inmeta-build-explorer.aspx</link>
            <description>&lt;p&gt;This weekend we at Inmeta release a free Visual Studio 2010 Team Explorer extensions that solves the problem with the Builds node in the Team Explorer not being hierarchic. For some reason, this part of the Team Explorer didn’t get the nice hierarchical folder structure that the Work items node got in 2010. The result is that, for a company that has several hundreds of builds in the same team project, it becomes very hard to navigate.&lt;/p&gt;  &lt;p&gt;The solution that we implemented is very simple and uses a naming convention to group the build definitions in folders. The default separator is ‘.’ (dot) which is prabably the most common convention used anyway. As it turns out, Microsoft DevDiv uses this convention internally, as posted    &lt;br /&gt;by &lt;a href="http://blogs.msdn.com/b/bharry/archive/2011/04/01/build-folders.aspx"&gt;Brian Harry&lt;/a&gt;. And they have a _lot_ of build definitions…. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Inmeta-Build-Explorer_83EB/wlEmoticon-smile_2.png" /&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;This is what the build explorer looks like:&lt;/p&gt;  &lt;p&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-jGCI0_3loyc/TZYy8TQStII/AAAAAAAAAE4/ejmqyPXLUtw/s320/Inmeta+build+explorer.png" width="287" height="320" /&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;As you can see, if you have a multi-part name, such as &lt;em&gt;Inmeta.TFS Exception Reporter.Production&lt;/em&gt;, you get two folders in the hierarchy. &lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The Build Explorer is available in the Visual Studio Gallery, either download it from &lt;a title="http://visualstudiogallery.msdn.microsoft.com/35daa606-4917-43c4-98ab-38632d9dbd45" href="http://visualstudiogallery.msdn.microsoft.com/35daa606-4917-43c4-98ab-38632d9dbd45"&gt;http://visualstudiogallery.msdn.microsoft.com/35daa606-4917-43c4-98ab-38632d9dbd45&lt;/a&gt;, or use the Visual Studio Extension Manager directly (search for Inmeta):    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Inmeta-Build-Explorer_83EB/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Inmeta-Build-Explorer_83EB/image_thumb.png" width="959" height="664" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;The extension was developed mostly by &lt;a href="http://larzjoakimnilzzon.blogspot.com/2011/04/inmeta-build-explorer.html"&gt;Lars Nilsson&lt;/a&gt;, with some smaller additions by myself and &lt;a href="http://geekswithblogs.net/terje/archive/2011/04/01/visual-studiondashbuild-folders-extension-for-team-explorer.aspx"&gt;Terje Sandström&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The source code is available at &lt;a href="http://tfsbuildfolders.codeplex.com"&gt;http://tfsbuildfolders.codeplex.com&lt;/a&gt;. Let us know what you think and if you want to contribute, contact me or Terje at the Codeplex site.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/144686.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2011/04/04/tfs-2010-inmeta-build-explorer.aspx</guid>
            <pubDate>Mon, 04 Apr 2011 07:38:07 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/144686.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2011/04/04/tfs-2010-inmeta-build-explorer.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/144686.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/144686.aspx</trackback:ping>
        </item>
        <item>
            <title>Integrating Code Metrics in TFS 2010 Build</title>
            <link>http://geekswithblogs.net/jakob/archive/2011/01/30/integrating-code-metrics-in-tfs-2010-build.aspx</link>
            <description>&lt;p&gt;&lt;font color="#0000ff"&gt;The build process template and custom activity described in this post is available here:      &lt;br /&gt;&lt;a title="http://cid-ee034c9f620cd58d.office.live.com/self.aspx/BlogSamples/Inmeta%20TFS%20Build%20Sample.zip" href="http://cid-ee034c9f620cd58d.office.live.com/self.aspx/BlogSamples/Inmeta%20TFS%20Build%20Sample.zip"&gt;http://cid-ee034c9f620cd58d.office.live.com/self.aspx/BlogSamples/Inmeta%20TFS%20Build%20Sample.zip&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Running code metrics has been available since VS 2008, but only from inside the IDE. Yesterday Microsoft finally released &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=edd1dfb0-b9fe-4e90-b6a6-5ed6f6f6e615"&gt;Visual Studio Code Metrics Power Tool 10.0&lt;/a&gt;, a command line tool that lets you run code metrics on your applications.  This means that it is now possible to perform code metrics analysis on the build server as part of your nightly/QA builds. In this post I will show how you can run the metrics command line tool from a build, and also a custom activity that reads the output and appends the results to the build log, and fails the build if the metric values exceeds certain (configurable) treshold values. &lt;/p&gt; The code metrics tool analyzes all the methods in the assemblies, measuring cyclomatic complexity, class coupling, depth of inheritance and lines of code. Then it calculates a M&lt;em&gt;aintainability Index&lt;/em&gt; from these values that is a measure of how maintanable this method is, between 0 (worst) and 100 (best). For information on how this value is calculated, see &lt;a href="http://blogs.msdn.com/b/codeanalysis/archive/2007/11/20/maintainability-index-range-and-meaning.aspx"&gt;http://blogs.msdn.com/b/codeanalysis/archive/2007/11/20/maintainability-index-range-and-meaning.aspx&lt;/a&gt;. After this it aggregates the information and present it at the class, namespace and module level as well.   &lt;p&gt;&lt;strong&gt;     &lt;br /&gt;Running Metrics.exe in a build definition       &lt;br /&gt;&lt;/strong&gt;Running the actual tool is easy, just use a InvokeProcess activity last in the &lt;em&gt;Compile the Project&lt;/em&gt; sequence, reference the metrics.exe file and pass the correct arguments and you will end up with a result XML file in the drop directory. Here is how it is done in the attached build process template:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_2.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_thumb.png" width="325" height="396" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In the above sequence I first assign the path to the code metrics result file ([BinariesDirectory]\result.xml) to a variable called &lt;em&gt;MetricsResultFile&lt;/em&gt;, which is then sent to the InvokeProcess activity in the Arguments property.     &lt;br /&gt;Here are the arguments for the InvokeProcess activity:     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_10.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_thumb_4.png" width="1125" height="184" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Note that we tell metrics.exe to analyze all assemblies located in the Binaries folder. You might want to do some more intelligent filtering here, you probably don’t want to analyze all 3rd party assemblies for example.    &lt;br /&gt;Note also the path to the metrics.exe, this is the default location when you install the Code Metrics power tool. You must of course install the power tool on all build servers.     &lt;br /&gt;    &lt;br /&gt;Using the standard output logging (in the Handle Standard Output/Handle Error Output sections), we get the following output when running the build:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_6.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_thumb_2.png" width="811" height="253" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Integrating Code Metrics into the build&lt;/strong&gt;     &lt;br /&gt;Having the results available next to the build result is nice, but we want to have results integrated in the build result itself, and also to affect the outcome of the build. The point of having QA builds that measure, for example, code metrics is to make it very clear how the code being built measures up to the standards of the project/company. Just having a XML file available in the drop location will not cause the developers to improve their code, but a (partially) failing build will! &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/wlEmoticon-smile_2.png" /&gt;&lt;/p&gt;  &lt;p&gt;To do this, we need to write a custom activity that parses the metrics result file, logs it to the build log and fails the build if the values frfom the metrics is below/above some predefined treshold values.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The custom activity performs the following steps&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Parses the XML. I’m using &lt;a href="http://linqtoxsd.codeplex.com/"&gt;Linq 2 XSD&lt;/a&gt; for this. Since the XML schema for the result file is available with the power tool, it is vey easy to generate code that lets you query the structure using standard Linq operators.       &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Runs through the metric result hierarchy and logs the metrics for each level and also verifies maintainability index and the cyclomatic complexity against the treshold values. The treshold values are defined in the build process template and are sent in as arguments to the custom activity&lt;strong&gt;        &lt;br /&gt;&lt;/strong&gt;&lt;/li&gt;    &lt;li&gt;If the treshold limits are exceeded, the activity either fails or partially fails the current build. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;For more information about the structure of the code metrics result file, read &lt;a href="http://blogs.msdn.com/b/camerons/archive/2011/01/28/code-metrics-from-the-command-line.aspx"&gt;Cameron Skinner's post about it&lt;/a&gt;. It is very simple and easy to understand. I won’t go through the code of the custom activity here, since there is nothing special about it and it is available for download so you can look at it and play with it yourself. &lt;/p&gt;  &lt;p&gt;The treshold values for Maintainability Index and Cyclomatic Complexity is defined in the build process template, and can be modified per build definition:    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_8.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Running-Code-Metrics-in-TFS-2010-Build_14A3A/image_thumb_3.png" width="492" height="146" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I have chosen the default values for these settings based on a post from my colleague &lt;a href="http://geekswithblogs.net/terje/Default.aspx"&gt;Terje Sandström&lt;/a&gt; - &lt;a href="http://geekswithblogs.net/terje/archive/2008/11/25/code-metrics---suggestions-for-appropriate-limits.aspx"&gt;Code Metrics - suggestions for approriate limits&lt;/a&gt;. When you think about it, this is quite an improvement compared to using code metrics inside the IDE, where the Red/Yellow/Green limits are fixed (and the default values are somewhat strange, see Terjes post for a discussion on this)&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;This is the first version of the code metrics integration with TFS 2010 Build, I will probably enhance the functionality and the logging (the “tree view” structure in the log becomes quite hard to read) soon.     &lt;br /&gt;I will also consider adding it to the &lt;a href="http://tfsbuildextensions.codeplex.com/"&gt;Community TFS Build Extensions&lt;/a&gt; site when it becomes a bit more mature.&lt;/p&gt;  &lt;p&gt;Another obvious improvement is to extend the data warehouse of TFS and push the metric results back to the warehouse and make it visible in the reports.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/143701.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2011/01/30/integrating-code-metrics-in-tfs-2010-build.aspx</guid>
            <pubDate>Sun, 30 Jan 2011 19:39:50 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/143701.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2011/01/30/integrating-code-metrics-in-tfs-2010-build.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/143701.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/143701.aspx</trackback:ping>
        </item>
        <item>
            <title>TFS 2010 Build Custom Activity for Merging Assemblies</title>
            <link>http://geekswithblogs.net/jakob/archive/2010/12/15/tfs-2010-build-custom-activity-for-merging-assemblies.aspx</link>
            <description>&lt;p&gt;&lt;font style="background-color: #ffffff" color="#0000ff"&gt;*** The sample build process template discussed in this post is available for download from here: &lt;/font&gt;&lt;a title="http://cid-ee034c9f620cd58d.office.live.com/self.aspx/BlogSamples/ILMerge.xaml" href="http://cid-ee034c9f620cd58d.office.live.com/self.aspx/BlogSamples/ILMerge.xaml"&gt;&lt;font style="background-color: #ffffff" color="#0000ff"&gt;http://cid-ee034c9f620cd58d.office.live.com/self.aspx/BlogSamples/ILMerge.xaml&lt;/font&gt;&lt;/a&gt;&lt;font style="background-color: #ffffff" color="#0000ff"&gt; ***&lt;/font&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;In my &lt;a href="http://geekswithblogs.net/jakob/archive/2010/12/08/dependency-replication-with-tfs-2010-build.aspx"&gt;previous post&lt;/a&gt; I talked about &lt;em&gt;library builds&lt;/em&gt; that we use to build and replicate dependencies between applications in TFS. This is typically used for common libraries and tools that several other application need to reference.&lt;/p&gt;  &lt;p&gt;When the libraries grow in size over time, so does the number of assemblies. So all solutions that uses the common library must reference all the necessary assemblies that they need, and if we for example do a refactoring and extract some   &lt;br /&gt;code into a new assembly, all the clients must update their references to reflect these changes, otherwise it won’t compile. &lt;/p&gt;  &lt;p&gt;To improve on this, we use a tool from Microsoft Research called &lt;em&gt;ILMerge&lt;/em&gt; (Download &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?familyid=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;amp;displaylang=en"&gt;from here&lt;/a&gt;). It can be used to merge several assemblies into one assembly that contains all types. If you haven’t used this tool before, you should check it out.     &lt;br /&gt;    &lt;br /&gt;Previously I have implemented this in builds using a simple batch file that contains the full command, something like this:    &lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;"%ProgramFiles(x86)%\microsoft\ilmerge\ilmerge.exe" /target:library /attr:ClassLibrary1.bl.dll /out:MyNewLibrary.dll ClassLibrary1.dll ClassLibrar2.dll ClassLibrary3.dll&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This merges 3 assemblies (ClassLibrary1, 2 and 3) into a new assembly called MyNewLibrary.dll. It will copy the attributes (file version, product version etc..) from ClassLibrary1.dll, using the /attr switch. For more info on ILMerge command line tool, see the above link.   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;This approach works, but requires a little bit too much knowledge for the developers creating builds, therefor I have implemented a custom activity that wraps the use of ILMerge. This makes it much simpler to setup a new build definition and have the build automatically do the merging.    &lt;br /&gt;The usage of the activity is then implemented as part of the Library Build process template mentioned in the previous post. For this article I have just created a simple build process template that only performs the ILMerge operation.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Below is the code for the custom activity. To make it compile, you need to reference the ILMerge.exe assembly.&lt;/p&gt;    &lt;p&gt;   &lt;/p&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:d5323aa1-79eb-4b24-8358-df9ccd3632c2" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 604px; height: 579px;background-color:White;overflow: auto;;font-family:Microsoft Sans Serif;font-size:8,25"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Activity for merging a list of assembies into one, using ILMerge
    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;sealed&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ILMergeActivity : BaseCodeActivity
    {
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; A list of file paths to the assemblies that should be merged
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        [RequiredArgument]
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; InArgument&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; InputAssemblies { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Full path to the generated assembly
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        [RequiredArgument]
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; InArgument&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; OutputFile { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Which input assembly that the attibutes for the generated assembly should be copied from.
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Optional. If not specified, the first input assembly will be used
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; InArgument&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; AttributeFile { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; Kind of assembly to generate, dll or exe
        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; InArgument&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;TargetKindEnum&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; TargetKind { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; If your activity returns a value, derive from CodeActivity&amp;lt;TResult&amp;gt;
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; and return the value from the Execute method.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Execute(CodeActivityContext context)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; message &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; InputAssemblies.Get(context).Aggregate(&lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;, (current, assembly) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; current &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; (assembly &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
            TrackMessage(context, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Merging &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; message &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; into &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; OutputFile.Get(context));
            ILMerge m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ILMerge();
            m.SetInputAssemblies(InputAssemblies.Get(context).ToArray());
            m.TargetKind &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; TargetKind.Get(context) &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; TargetKindEnum.Dll &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; ILMerge.Kind.Dll : ILMerge.Kind.Exe;
            m.OutputFile &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; OutputFile.Get(context);
            m.AttributeFile &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;String.IsNullOrEmpty(AttributeFile.Get(context)) &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; AttributeFile.Get(context) : InputAssemblies.Get(context).First();
            m.SetTargetPlatform(RuntimeEnvironment.GetSystemVersion().Substring(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;), RuntimeEnvironment.GetRuntimeDirectory());
            m.Merge();

            TrackMessage(context, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Generated &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.OutputFile);
        }
    }
    [Browsable(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;)]
    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;enum&lt;/span&gt;&lt;span style="color: #000000;"&gt; TargetKindEnum
    {
        Dll,
        Exe
    }&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;NB&lt;/strong&gt;: The activity inherits from a BaseCodeActivity class which is an internal helper class which contains some methods and properties useful for moste custom activities. In this case, it uses the TrackeMessage method for writing

  &lt;br /&gt;to the build log. You either need to remove the TrackMessage method calls, or implement this yourself (which is not very hard… &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/wlEmoticon-smile_2.png" /&gt;)&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;The custom activity has the following input arguments:&lt;/p&gt;

&lt;table border="0" cellspacing="0" cellpadding="2" width="703"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="200"&gt;&lt;strong&gt;InputAssemblies&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="501"&gt;A list with the (full) paths to the assemblies to merge&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="200"&gt;&lt;strong&gt;OutputFile&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="501"&gt;The name of the resulting merged assembly&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="200"&gt;&lt;strong&gt;AttributeFile&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="501"&gt;Which assembly to use as the template for the attribute of the merged assembly. This argument is optional and if left blank, the first assembly in the input list is used&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="200"&gt;&lt;strong&gt;TargetKind&lt;/strong&gt;&lt;/td&gt;

      &lt;td valign="top" width="501"&gt;Decides what type of assembly to create, can be either a dll or an exe&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Of course, there are more switches to the ILMerge.exe, and these can be exposed as input arguments as well if you need it.&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;To show how the custom activity can be used, I have attached a build process template (see link at the top of this post) that merges the output of the projects being built (CommonLibrary.dll and CommonLibrary2.dll) into a merged assembly (NewLibrary.dll).

  &lt;br /&gt;The build process template has the following custom process parameters:

  &lt;br /&gt;

  &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_thumb.png" width="558" height="192" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The Assemblies To Merge argument is passed into a FindMatchingFiles activity to located all assemblies that are located in the BinariesDirectory folder after the compilation has been performed by Team Build.
  &lt;br /&gt;Here is the complete sequence of activities that performs the merge operation. It is located at the end of the Try, Compile, Test and Associate… sequence:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_thumb_1.png" width="501" height="798" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It splits the AssembliesToMerge parameter and appends the full path (using the BinariesDirectory variable) and then enumerates the matching files using the FindMatchingFiles activity.&lt;/p&gt;

&lt;p&gt;When running the build, you can see that it merges two assemblies into a new one:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_thumb_2.png" width="1157" height="255" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;
  &lt;/p&gt;&lt;p&gt;And the merged assembly (and associated pdb file) is copied to the drop location together with the rest of the assemblies:
    &lt;br /&gt;

    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/TFS-2010-Build-Custom-Activity-for-Mergi_CBA1/image_thumb_3.png" width="626" height="189" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/143145.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2010/12/15/tfs-2010-build-custom-activity-for-merging-assemblies.aspx</guid>
            <pubDate>Wed, 15 Dec 2010 00:59:29 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/143145.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2010/12/15/tfs-2010-build-custom-activity-for-merging-assemblies.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/143145.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/143145.aspx</trackback:ping>
        </item>
        <item>
            <title>Dependency Replication with TFS 2010 Build</title>
            <link>http://geekswithblogs.net/jakob/archive/2010/12/08/dependency-replication-with-tfs-2010-build.aspx</link>
            <description>&lt;p&gt;Some time ago, I wrote a &lt;a href="http://geekswithblogs.net/jakob/archive/2009/03/05/implementing-dependency-replication-with-tfs-team-build.aspx"&gt;post&lt;/a&gt; about how to implement dependency replication using TFS 2008 Build. We use this for &lt;em&gt;Library builds&lt;/em&gt;, where we set up a build definition for a common library, and have the build check the resulting assemblies back into source control. The folder&lt;strong&gt; is&lt;/strong&gt; then branched to the applications that need to reference the common library. See the above post for more details.&lt;/p&gt;  &lt;p&gt;Of course, we have reimplemented this feature in TFS 2010 Build, which results in a much nicer experience for the developer who wants to setup a new library build. Here is how it looks:   &lt;br /&gt;    &lt;br /&gt;There is a separate build process template for library builds registered in all team projects    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_2.png"&gt;&lt;strong&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_thumb.png" width="1027" height="209" /&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;The following properties are used to configure the library build:    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_thumb_1.png" width="942" height="230" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;strong&gt;Deploy Folder in Source Control &lt;/strong&gt;is the server path where the assemblies should be checked in    &lt;br /&gt;&lt;strong&gt;DeploymentFiles&lt;/strong&gt; is a list of files and/or extensions to what files to check in. Default here is *.dll;*.pdb which means that all assemblies and debug symbols will be checked in. We can also type for example &lt;em&gt;CommonLibrary.*;SomeOtherAssembly.dll &lt;/em&gt;in order to exclude other assemblies    &lt;br /&gt;    &lt;br /&gt;You can also see that we are versioning the assemblies as part of the build. This is important, since the resulting assemblies will be deployed together with the referencing application. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;When the build executes, it will see of the matching assemblies exist in source control, if not, it will add the files automatically:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_8.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_thumb_3.png" width="999" height="306" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;After the build has finished, we can see in the history of the TestDeploy folder that the build service account has in fact checked in a new version:    &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/image_thumb_2.png" width="554" height="159" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nice! &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Ler" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Dependency-Replication-with-TFS-2010-Bui_11F08/wlEmoticon-smile_2.png" /&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;The implementation of the library build process template is not very complicated, it is a combination of customization of the build process template and some custom activities.    &lt;br /&gt;We use the generic TFActivity (&lt;a title="http://geekswithblogs.net/jakob/archive/2010/11/03/performing-checkins-in-tfs-2010-build.aspx" href="http://geekswithblogs.net/jakob/archive/2010/11/03/performing-checkins-in-tfs-2010-build.aspx"&gt;http://geekswithblogs.net/jakob/archive/2010/11/03/performing-checkins-in-tfs-2010-build.aspx&lt;/a&gt;) to check in and out files, but for the part that checks if a file exists     &lt;br /&gt;and adds it to source control, it was easier to do this in a custom activity:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:603acbcf-4154-4668-872f-1be99c5c2c82" class="wlWriterEditableSmartContent"&gt;&lt;pre style=" width: 604px; height: 579px;background-color:White;overflow: auto;;font-family:Microsoft Sans Serif;font-size:8,25"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;sealed&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; AddFilesToSourceControl : BaseCodeActivity
    {
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Files to add to source control&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        [RequiredArgument]
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; InArgument&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;IEnumerable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Files { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        [RequiredArgument]
        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; InArgument&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Workspace&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; Workspace { &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;get&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;set&lt;/span&gt;&lt;span style="color: #000000;"&gt;; }

        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; If your activity returns a value, derive from CodeActivity&amp;lt;TResult&amp;gt;
        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; and return the value from the Execute method.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Execute(CodeActivityContext context)
        {
            &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (var file &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; Files.Get(context))
            {
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;File.Exists(file))
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ApplicationException(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Could not locate &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; file);
                }

                var ws &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Workspace.Get(context);
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; serverPath &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ws.TryGetServerItemForLocalItem(file);
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;( &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;String.IsNullOrEmpty(serverPath))
                {
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt;ws.VersionControlServer.ServerItemExists(serverPath, ItemType.File))
                    {
                        TrackMessage(context, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Adding file &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; file);
                        ws.PendAdd(file);
                    }
                    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                    {
                        TrackMessage(context, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;File &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; file &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; already exists in source control&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);                        
                    }
                }
                &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
                {
                    TrackMessage(context, &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;No server path for &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; file);
                }
            }
        }
    }
&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;



&lt;p&gt;This build template is a very nice tool that makes it easy to do dependency replication with TFS 2010. Next, I will add funtionality for automatically merging the assemblies (using ILMerge) as part of the build, we do this to keep the number of references to a minimum.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/143056.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2010/12/08/dependency-replication-with-tfs-2010-build.aspx</guid>
            <pubDate>Wed, 08 Dec 2010 07:02:09 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/143056.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2010/12/08/dependency-replication-with-tfs-2010-build.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/143056.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/143056.aspx</trackback:ping>
        </item>
        <item>
            <title>Performing Checkins in TFS 2010 Build</title>
            <link>http://geekswithblogs.net/jakob/archive/2010/11/03/performing-checkins-in-tfs-2010-build.aspx</link>
            <description>&lt;p&gt;*** The custom activity is availabe for download here: &lt;a title="http://cid-ee034c9f620cd58d.office.live.com/browse.aspx/BlogSamples?uc=1" href="http://cid-ee034c9f620cd58d.office.live.com/browse.aspx/BlogSamples?uc=1"&gt;http://cid-ee034c9f620cd58d.office.live.com/browse.aspx/BlogSamples?uc=1&lt;/a&gt; ***&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Often when creating different types of release builds (e.g. where you build something that should be installed or consumed by other applications) there is a need to check in the results of the build back   &lt;br /&gt;to source control. A common build type for us at Inmeta is &lt;em&gt;Library Builds&lt;/em&gt;, which we use for common libraries that are shared among several applications. We have created a special build process template    &lt;br /&gt;for this scenario that handles versioning, copying of the resulting binaries to a pre-defined folder, optionally merges the assemblies using ILMerge, and finally checking that binaries back to TFS as part of the build.&lt;/p&gt;  &lt;p&gt;When it comes to communicating with TFS source control during a build, I find that the most flexible appraoch is to wrap the command line tool &lt;em&gt;tf.exe&lt;/em&gt;. This tool has all the functionality you need, and if you choose    &lt;br /&gt;to implement custom activities for the same functionality you would need to expose a lot of functionality that is very simple to call using tf.exe. There are two major drawbacks of this approach however:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;You need tf.exe on the build server, e.g. you must install Team Explorer. Generally it is a very good principle to keep the build server as minimal as possible.&lt;/li&gt;    &lt;li&gt;It is not that easy to invoke command line tools in TFS 2010 Build, it is hard to get the syntax and the paths correct. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you can live with the first drawback, then we can at least reduce the problems of the other drawback by creating a simple custom activity that wraps some of the nitty gritty details of calling tf.exe.   &lt;br /&gt;This is a simple activity, but I have found it useful and hopefully some of you will too. &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Here is an example of how it looks when it is used in a build process template:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Performing-Checkins-in-TFS-2010-Build_13106/image_4.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Performing-Checkins-in-TFS-2010-Build_13106/image_thumb_1.png" width="746" height="253" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Note:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The property &lt;em&gt;Command&lt;/em&gt; is an enum type which just enumerates all possible commands to tf.exe. This makes it easy to select the correct command and stop you from getting syntax errors.      &lt;br /&gt;The enum is available as well in the download packages      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;You don’t need to know about how tf.exe is called     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;There is an IgnoreError boolean property that will ignore any errors if true (default is false)     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;The Arguments property is the argument to the tf.exe command. In this case, the resulting command will be &lt;em&gt;tf.exe checkin *.dll /recursive       &lt;br /&gt;&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;WorkingDirectory is mapped to the InvokeProcess.WorkingDirectory. Generally when performing source control operations using tf.exe, you should point the working directory somewhere inside the workspace.     &lt;br /&gt;By doing so, you don’t need to bother about spefcifying workspace or collection &lt;a href="s."&gt;URL:s.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;   &lt;br /&gt;The custom activity itself is pretty simple, it just wraps the call to InvokeProcess, with the standard output/error logging and error checking:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Performing-Checkins-in-TFS-2010-Build_13106/image_6.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://geekswithblogs.net/images/geekswithblogs_net/jakob/Windows-Live-Writer/Performing-Checkins-in-TFS-2010-Build_13106/image_thumb_2.png" width="557" height="595" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This activity is very simple, and can definitely be exended. Let me know if you find it useful and if you have any suggestions for improvements.&lt;/p&gt; &lt;img src="http://geekswithblogs.net/jakob/aggbug/142586.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jakob Ehn</dc:creator>
            <guid>http://geekswithblogs.net/jakob/archive/2010/11/03/performing-checkins-in-tfs-2010-build.aspx</guid>
            <pubDate>Wed, 03 Nov 2010 09:20:53 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/jakob/comments/142586.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/jakob/archive/2010/11/03/performing-checkins-in-tfs-2010-build.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/jakob/comments/commentRss/142586.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/jakob/services/trackbacks/142586.aspx</trackback:ping>
        </item>
    </channel>
</rss>
