<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jason Prickett's Blog : Team Build</title><link>http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx</link><description>Tags: Team Build</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>TFS 2010 – What’s New On The Build Explorer?</title><link>http://blogs.msdn.com/jpricket/archive/2009/06/15/tfs-2010-what-s-new-on-the-build-explorer.aspx</link><pubDate>Mon, 15 Jun 2009 16:39:47 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9753197</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/9753197.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=9753197</wfw:commentRss><description>&lt;p&gt;&lt;strong&gt;The Queued Tab:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/TFS2010WhatsNewOnTheBuildExplorer_87D2/image_6.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="283" alt="image" src="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/TFS2010WhatsNewOnTheBuildExplorer_87D2/image_thumb_2.png" width="647" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;So, as you can see not much has changed on the Queued tab of the build explorer since VSTS 2008, but if you look close, there are a few changes.&lt;/p&gt;  &lt;p&gt;1. There is a new filter you can apply - “Only show builds requested by me”. This filter will limit the results to only those builds you directly caused by checking in or manually queuing it. This is really helpful when there are lots of builds for your team project and you only care about yours.&lt;/p&gt;  &lt;p&gt;2. There is a new column on the left. If you hover over it, you see it’s the “Reason” column. This shows you what caused the build to start. In the picture above, you can see two builds. The one with the icon was triggered by a checkin and the other was manually queued. &lt;/p&gt;  &lt;p&gt;3. All columns except the image columns are sizeable. They start off adjusted to their data, but you can change that. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Completed Tab:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/TFS2010WhatsNewOnTheBuildExplorer_87D2/image_8.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="280" alt="image" src="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/TFS2010WhatsNewOnTheBuildExplorer_87D2/image_thumb_3.png" width="647" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Likewise on the Completed tab, not much has changed. In fact, it has the same changes as the Queued tab – a new filter, a new column, and sizeable columns. They work the same here as on the Queued tab.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9753197" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category><category domain="http://blogs.msdn.com/jpricket/archive/tags/VSTS+2010/default.aspx">VSTS 2010</category></item><item><title>TFS 2010 Beta1 – Build DEtails View Log View section</title><link>http://blogs.msdn.com/jpricket/archive/2009/05/18/tfs-2010-beta1-build-details-view-log-view-section.aspx</link><pubDate>Mon, 18 May 2009 21:55:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9625745</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/9625745.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=9625745</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/TFS2010Beta1BuildDEtailsViewLogViewsecti_CD83/BuildDetailView-Log-InProgress_2.png"&gt;&lt;img title="BuildDetailView-Log-InProgress" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="517" alt="BuildDetailView-Log-InProgress" src="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/TFS2010Beta1BuildDEtailsViewLogViewsecti_CD83/BuildDetailView-Log-InProgress_thumb.png" width="602" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The picture above is of the Log View of the new Build Details View in Visual Studio Team System 2010. See my &lt;a href="http://blogs.msdn.com/jpricket/archive/2009/05/12/tfs-2010-beta1-build-details-view-summary-section.aspx"&gt;previous post on the Summary View&lt;/a&gt; for more information on the items above the words “Activity Log”. The log view can be seen by opening an in-progress build like the one shown above or by clicking the “View Log” link on a completed build.&lt;/p&gt;  &lt;p&gt;Here are some things to notice about this view:&lt;/p&gt;  &lt;p&gt;1. There are links (“Next Error” and “Next Warning”) to quickly jump to the first or next error or warning. The Log View can be quite long so this should help you find the errors more quickly. Of course, the error messages will also show up on the Summary view, so you may not need to come here at all. &lt;/p&gt;  &lt;p&gt;2. The “Show Property Values” link will expand the log view even further and show you all the property values that were logged for the build activities. Because these values can greatly increase the size of the log, they are turned off by default.&lt;/p&gt;  &lt;p&gt;3. On the right is a duration column. This shows you the duration of each build activity. If you are trying to speed up your builds, this information should help you determine what build activities are taking the longest. Note that the values roll up. So, parent duration values are approximately the sum of their children’s durations.&lt;/p&gt;  &lt;p&gt;4. The data is presented in a hierarchy. This hierarchy maps perfectly to the build process template (more on that in a later post). This allows you to follow the path that the build took through the template and possibly correct problems with your custom templates. Note: showing the property values is important to understanding the flow.&lt;/p&gt;  &lt;p&gt;5. The “play” icon in front of some of the lines indicates that those build activities are currently in progress. Another way to follow along as a build follows the process template logic. Note that a parent activity is considered in-progress if any of its children are in-progress.&lt;/p&gt;  &lt;p&gt;6. Lastly, like the summary view, there is a slider in the bottom right corner that allows you to zoom in or out on the log view.&lt;/p&gt;  &lt;p&gt;&lt;font size="4"&gt;&lt;em&gt;I hope this gives you some more insight into the 2010 release!&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9625745" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category><category domain="http://blogs.msdn.com/jpricket/archive/tags/VSTS+2010/default.aspx">VSTS 2010</category></item><item><title>tFS 2010 Beta1 – Build Details View Summary section</title><link>http://blogs.msdn.com/jpricket/archive/2009/05/12/tfs-2010-beta1-build-details-view-summary-section.aspx</link><pubDate>Tue, 12 May 2009 23:23:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9608074</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/9608074.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=9608074</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/tFS2010Beta1BuildDetailsViewSummarysecti_D3D6/BuildDetailView-Summary-CompilationFailure_2.png"&gt;&lt;img title="BuildDetailView-Summary-CompilationFailure" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="584" alt="BuildDetailView-Summary-CompilationFailure" src="http://blogs.msdn.com/blogfiles/jpricket/WindowsLiveWriter/tFS2010Beta1BuildDetailsViewSummarysecti_D3D6/BuildDetailView-Summary-CompilationFailure_thumb.png" width="648" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The picture above is of the new “Build Report” in TFS 2010. I prefer the term Build Details View, because it is not actually a TFS report object. The view has completely changed, so let me take you on a quick tour:&lt;/p&gt;  &lt;p&gt;1. The first thing you may notice is that this is a failed build. The icon in the upper left corner notifies you of the status (in progress, succeeded, partially succeeded, or failed). &lt;/p&gt;  &lt;p&gt;2. The next thing on that same line is the build number “Build HW_20090512.3” and the status is repeated as a word. Then comes the Build Quality. That’s right you can change the build quality right here on the build details view.&lt;/p&gt;  &lt;p&gt;3. The links on the next line allow you to view the summary page (that’s the page we see above), view the log page (need another post for that one), open the drop folder, and delete the build. &lt;/p&gt;  &lt;p&gt;4. &lt;strong&gt;The bar graph&lt;/strong&gt; - now things really start getting interesting. This is a graph of the last 9 builds for the same definition. The small triangle denotes this build. The height of the bars show the relative time that the build took and the color indicates the status. You can also hover over the bar to get a tool tip with that information. This graph is really helpful when the build is in progress, because you can see how long the other builds took and guess how much longer this one will be :)&lt;/p&gt;  &lt;p&gt;5. The rest of the information beside the graph includes who started the build (jpricket), what definition was triggered (Build HW), what changeset was built, how long the build took, what build controller was used, and when it was started. A lot of info in a small space!&lt;/p&gt;  &lt;p&gt;6. &lt;strong&gt;Latest Activity&lt;/strong&gt; – this section includes who last modified the build and when. It also lists any work items that were opened during the build. Notice the link! Clicking on the link will open the work item :)&lt;/p&gt;  &lt;p&gt;7. &lt;strong&gt;Summary&lt;/strong&gt; – This section contains a lot of information. The main purpose is to report the results of the build. It is divided by Configurations with another section at the end for any Errors or Warnings that may have happened outside of a configuration. Each configuration has four sections: errors and warnings, projects/solutions compiled, test results, and code coverage results. Notice the links! You can go to the actual build log for the configuration, or you can click on a particular error and go straight to the source line. (this actually downloads the file and opens the exact version that the Build Machine was attempting to build).&lt;/p&gt;  &lt;p&gt;8. &lt;strong&gt;Impacted Tests&lt;/strong&gt; – this section is completely new and allows you to see which tests were impacted by the changes that were checked in.&lt;/p&gt;  &lt;p&gt;9. If there were test results, you would also have a link to them, just like you did in TFS 2008.&lt;/p&gt;  &lt;p&gt;10. Associated changesets and work items will also show up in their own sections for a successful build. They also have links to open the Changeset details or the Work Item.&lt;/p&gt;  &lt;p&gt;11. Oh, and that slider in the bottom right hand corner allows you to zoom in or out.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;font size="3"&gt;&lt;strong&gt;&lt;em&gt;Hopefully this encourages you to download the Beta and start playing with it!&lt;/em&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9608074" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category><category domain="http://blogs.msdn.com/jpricket/archive/tags/VSTS+2010/default.aspx">VSTS 2010</category></item><item><title>Keeping Version Control Labels When Team Builds Are Deleted in TFS 2008 SP1</title><link>http://blogs.msdn.com/jpricket/archive/2008/09/30/keeping-version-control-labels-when-team-builds-are-deleted-in-tfs-2008-sp1.aspx</link><pubDate>Tue, 30 Sep 2008 16:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8970303</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/8970303.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=8970303</wfw:commentRss><description>&lt;P&gt;We have had quite a few complaints about the fact that we delete the labels created during a build when the build is deleted. The reason this behavior was added was to keep from creating a ton of labels for CI builds. But some customers still want the labels to exist after the build has been deleted. Long term we will allow you to choose what gets deleted with the build. But for now, we have made a change that is available in Team Foundation Server 2008 SP1 that you should like.&lt;/P&gt;
&lt;P&gt;If you want to always keep labels even though builds are being deleted by retention policies or manually, you can simply make a change on the Application Tier in the web.config file. Here are the details:&lt;/P&gt;
&lt;P&gt;1) Locate the Team Foundation Web.Config file on the Application Tier.&lt;/P&gt;
&lt;P&gt;2) Add a flag to the Web.config file to specify that labels should not be deleted. When this value is present, labels are not deleted from Source Control. The default behavior is still the same as RTM; labels get deleted with their corresponding builds. Here is an example of what that line in the web.config file would look like: &lt;BR&gt;&amp;lt;add key="PreserveLabelsOnBuildDeletion" value="True"/&amp;gt; &lt;/P&gt;
&lt;P&gt;3) Run IISReset to force the changes to be used.&lt;/P&gt;
&lt;P&gt;I hope this helps those customers that use labels a lot.&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8970303" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Filtering the Build Status Change Event (BuildStatusChangeEvent)</title><link>http://blogs.msdn.com/jpricket/archive/2008/05/13/filtering-the-build-status-change-event-buildstatuschangeevent.aspx</link><pubDate>Tue, 13 May 2008 15:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8500024</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/8500024.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=8500024</wfw:commentRss><description>&lt;P&gt;In an &lt;A href="http://blogs.msdn.com/jpricket/archive/2006/09/05/how-to-filter-the-build-completion-event.aspx" mce_href="http://blogs.msdn.com/jpricket/archive/2006/09/05/how-to-filter-the-build-completion-event.aspx"&gt;previous post&lt;/A&gt; (long long ago), I described some scenarios around why you would want to subscribe to change the work item tracking subscription to the build completion event. The purpose there was to help users "correct" the subscription that came out of the box. In this post, I would like to answer a question I got from a user about how to subscribe to the other build event - BuildStatusChangeEvent. The question was basically this: How do I get notified when the build quality changes from 'X' to 'Y'?&lt;/P&gt;
&lt;P&gt;First, let me say that the name of this event is all wrong. It does not fire when the status of a build changes, but rather when the quality field of the build changes. In the future, it may do more, but not for now. The name aside, it is important to look at the structure of the xml that is sent when the event fires. It is actually very short. Here is an example:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;lt;?xml version="1.0" encoding="utf-16"?&amp;gt;&amp;lt;BuildStatusChangeEvent xmlns:xsi="&lt;A href="http://www.w3.org/2001/XMLSchema-instance" ? mce_href="http://www.w3.org/2001/XMLSchema-instance"&gt;http://www.w3.org/2001/XMLSchema-instance"&lt;/A&gt; xmlns:xsd="&lt;A href="http://www.w3.org/2001/XMLSchema" ? mce_href="http://www.w3.org/2001/XMLSchema"&gt;http://www.w3.org/2001/XMLSchema"&lt;/A&gt;&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;TeamFoundationServerUrl&amp;gt;http://jpricket-test:8080&amp;lt;/TeamFoundationServerUrl&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;TeamProject&amp;gt;TestProj&amp;lt;/TeamProject&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;Title&amp;gt;TestProj Build CSharp_Tests_20080507.3 Quality Changed To Ready for Deployment&amp;lt;/Title&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;Id&amp;gt;CSharp_Tests_20080507.3&amp;lt;/Id&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;Url&amp;gt;&lt;A href="http://jpricket-test:8080/Build/Build.aspx?artifactMoniker=9" mce_href="http://jpricket-test:8080/Build/Build.aspx?artifactMoniker=9"&gt;http://jpricket-test:8080/Build/Build.aspx?artifactMoniker=9&lt;/A&gt;&amp;lt;/Url&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;TimeZone&amp;gt;Eastern Daylight Time&amp;lt;/TimeZone&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;TimeZoneOffset&amp;gt;-04:00:00&amp;lt;/TimeZoneOffset&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;ChangedTime&amp;gt;5/9/2008 3:05:33 PM&amp;lt;/ChangedTime&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;StatusChange&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;FieldName&amp;gt;Quality&amp;lt;/FieldName&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;OldValue&amp;gt;Lab Test Passed&amp;lt;/OldValue&amp;gt; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;NewValue&amp;gt;Ready for Deployment&amp;lt;/NewValue&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;/StatusChange&amp;gt; &lt;BR&gt;&amp;nbsp; &amp;lt;ChangedBy&amp;gt;NORTHAMERICA\jpricket&amp;lt;/ChangedBy&amp;gt; &lt;BR&gt;&amp;lt;/BuildStatusChangeEvent&amp;gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The important bit is under the StatusChange node which also makes it a little more interesting than the last post that I did. To filter this event in any useful way requires you to know a little more about XPath. Or at least how the "path" to the OldValue and NewValue fields are formed. It's actually pretty simple. Ignore the root node BuildStatusChangeEvent and then use a slash between each node that you need to reference in the path. For example, if you want to filter on the NewValue field, you might want to use the filter expression 'StatusChange/NewValue'='Ready for Deployment'.&lt;/P&gt;
&lt;P&gt;Finally, here are some scenarios that you might find yourself in:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;I want to be notified when a build is marked as "Released"&lt;/LI&gt;
&lt;LI&gt;I want to be notified when the build quality is removed (only applies to 2008 and above)&lt;/LI&gt;
&lt;LI&gt;I want to be notified when the build changes from "Rejected" to "Released"&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;And here are the filters that correspond to those scenarios:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;'StatusChange/NewValue'='Released'&lt;/LI&gt;
&lt;LI&gt;'StatusChange[count(NewValue) = 0]' &amp;lt;&amp;gt; null AND 'StatusChange[count(OldValue) &amp;gt; 0]' &amp;lt;&amp;gt; null&lt;/LI&gt;
&lt;LI&gt;'StatusChange/OldValue'='Rejected' AND 'StatusChange/NewValue'='Released'&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The first and last are exactly what you might expect. But the second filter was quite a challenge. It turns out that when OldValue or NewValue are null, they are not included in the XML at all. So, to see if NewValue was set to null, we have to get the StatusChange nodes that have a count of NewValue nodes equal to zero. If any StatusChange nodes are returned then that half of the filter is true. The other half is just the opposite. We want to make sure that the StatusChange node has at least 1 OldValue field. The syntax of the xPath query is a little hard to get right, but it does exactly what we want.&lt;/P&gt;
&lt;P&gt;Hopefully, this will help you with this and other TFS Events! I have attached the code that I used to add these subscriptions to my server. It is very similar to the code in my previous post.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8500024" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/jpricket/attachment/8500024.ashx" length="23426" type="application/x-zip-compressed" /><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Where's the TfsBuild.proj file for this Definition?</title><link>http://blogs.msdn.com/jpricket/archive/2008/05/05/where-s-the-tfsbuild-proj-file-for-this-definition.aspx</link><pubDate>Mon, 05 May 2008 15:58:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8460376</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/8460376.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=8460376</wfw:commentRss><description>&lt;p&gt;In Team Build 2005, the &amp;quot;definition&amp;quot; of the build was the same as the TfsBuild.proj file. However, in 2008, we changed this so that the TfsBuild.proj only held some of the information for the build. The rest of the information (like retention policies, workspace definition, and triggers) were all stored in the build database. 2008 even allows two different Build Definitions to share the same TfsBuild.proj file. &lt;/p&gt;  &lt;p&gt;Unfortunately, due to this diversion of &amp;quot;definition&amp;quot; and source control file (TfsBuild.proj), users have found it difficult to easily get to the TfsBuild.proj file from the UI. Okay, you can find it, but you have to follow this procedure:&lt;/p&gt;  &lt;p&gt;1) open the associated definition from team explorer&lt;/p&gt;  &lt;p&gt;2) go to the project file tab&lt;/p&gt;  &lt;p&gt;3) write down the server path&lt;/p&gt;  &lt;p&gt;4) open Source Control Explorer &lt;/p&gt;  &lt;p&gt;5) Navigate to the right server path&lt;/p&gt;  &lt;p&gt;6) look for the file TfsBuild.proj&lt;/p&gt;  &lt;p&gt;Well, in 2008 SP1, you don't have to do all that work any more. Simply right click on the definition in team explorer and choose &amp;quot;View Configuration Folder&amp;quot;. This menu item will do all the of the above for you. In future versions, we may even dream of world without TfsBuild.proj files :o&lt;/p&gt;  &lt;p&gt;For more information on all the new features in Team Foundation Server 2008 SP1, see &lt;a href="http://blogs.msdn.com/bharry/archive/2008/04/28/team-foundation-server-2008-sp1.aspx"&gt;bharry's blog&lt;/a&gt; about them.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8460376" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Changing the recursion type for the initial "Get" that Team Build does</title><link>http://blogs.msdn.com/jpricket/archive/2007/12/10/changing-the-recursion-type-for-the-initial-get-that-team-build-does.aspx</link><pubDate>Mon, 10 Dec 2007 16:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6723450</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/6723450.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=6723450</wfw:commentRss><description>&lt;P&gt;In Visual Studio&amp;nbsp;Team System 2008, the build machine downloads the files that it needs to launch MSBuild before it creates any workspaces.&amp;nbsp;Because this initial "get" is before MSBuild is called,&amp;nbsp;users don't get much say in what gets downloaded.&amp;nbsp;By default, the build machine downloads all the files in the ConfigurationFolderPath of the build definition that is being built.&amp;nbsp;You specify that path in the Build Definition dialog. Everthing at the root of that folder is then downloaded before the build starts.&lt;/P&gt;
&lt;P&gt;The problem that some people have run into is that we only download the root of the folder. They have some assemblies or other specific build files that are nessesary in subfolders of that location. Luckily we thought of that. You can change the download parameters so that all subdirectories are downloaded as well. Be careful, however, if you specify to download everything, you will get everything under that folder that exists in version control. You cannot cloak anything out. Also note that this "fix" is per build machine, not build, and not build definition. &lt;/P&gt;
&lt;P&gt;Here are the steps:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;Log into the build machine that you want to change (you probably need to be an admin on the box).&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;Locate the TFSBuildService.exe.config file (most likely in "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies")&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;open it in notepad or some other text editor&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;Near the bottom (before the /appsettings closing tag) add the following line: &lt;/DIV&gt;&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;&lt;STRONG&gt;&amp;lt;add key="ConfigurationFolderRecursionType" value="Full" /&amp;gt;&lt;/STRONG&gt;&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;other values include OneLevel or None. OneLevel is the default.&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;Save the file&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV align=left&gt;Restart the "Visual Studio Team Foundation Build Service" from the Services control panel applet.&lt;/DIV&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P align=left&gt;That's it. I hope this helps!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6723450" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Stopping a Build -&gt; Cancelling a Workflow</title><link>http://blogs.msdn.com/jpricket/archive/2007/11/01/stopping-a-build-cancelling-a-workflow.aspx</link><pubDate>Thu, 01 Nov 2007 15:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5813300</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/5813300.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=5813300</wfw:commentRss><description>&lt;P&gt;This post continues my quest to learn more about Windows Workflow and share that experience with you. It assumes knowledge of Windows Workflow. If you don't understand some of the concepts please take a look at one of the books that I mentioned in &lt;A class="" href="http://blogs.msdn.com/jpricket/archive/2007/10/09/my-introduction-to-windows-workflow-foundation-wf.aspx" mce_href="http://blogs.msdn.com/jpricket/archive/2007/10/09/my-introduction-to-windows-workflow-foundation-wf.aspx"&gt;my first WF post&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;One of the operations that we require is the ability to Stop a Build that is in progress. This corresponds to Terminating a workflow. However, in our investigation of how WF handles Terminate, we discovered that it isn't what we really want. Termination of a workflow does not end the workflow immediately. That's not so bad, but it also doesn't give the workflow a chance to clean up anything (i.e. there are no handlers for termination). So, we looked into Cancellation of a workflow instead of using terminate.&lt;/P&gt;
&lt;P&gt;We found that it is really hard to cancel a workflow. First of all there is not a WorkflowInstance.Cancel method. So, if you plan to cancel the workflow from outside the instance, you have a hurdle to jump already. But if your workflow is like ours and you can put your own Activity class at the root, you can leap the hurdle pretty easily. What we did was to have the root activity create a Queue (we called it the cancellation queue) with a well known name (a hard coded Guid). From there it seemed obvious that we could Queue an item to this well known Queue and from within the instance call CancelActivity on the root. But alas, that is not allowed. You can only call CancelActivity on the currently executing activity. Bummer! So, we tried cancelling the executing activity, but that ended up just continuing the execution of the next activity after it which wasn't cancelled. Double Bummer!&lt;/P&gt;
&lt;P&gt;So, our final solution was to Throw when we got something in the Queue. Throwing automatically causes all activities to cancel including the active one. It also gives the workflow a place to do any clean up that needs to be done by catching the CancellationException at the top of the workflow.&lt;/P&gt;
&lt;P&gt;It wasn't pretty, but we were able to accomplish what we wanted. Here is a summary of the steps that actually worked for us:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In the root level activity (which is our own class derived from one of the WF activities) we create a special Queue just for this situation. The Queue has a constant GUID for the name&lt;/LI&gt;
&lt;LI&gt;From outside the workflow, we get the WorkflowInstance and Enqueue an item into this special Queue.&lt;/LI&gt;
&lt;LI&gt;When an item is enqueued, our activity class Throws a special exception. That causes everything to get cancelled.&lt;/LI&gt;
&lt;LI&gt;Our cancellation handlers can do any clean up.&lt;/LI&gt;
&lt;LI&gt;We have a special fault handler that also catches this special exception and eats it, so that the workflow completes normally.&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5813300" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category><category domain="http://blogs.msdn.com/jpricket/archive/tags/Workflow/default.aspx">Workflow</category></item><item><title>My Introduction to Windows Workflow Foundation (WF)</title><link>http://blogs.msdn.com/jpricket/archive/2007/10/09/my-introduction-to-windows-workflow-foundation-wf.aspx</link><pubDate>Tue, 09 Oct 2007 14:59:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5381694</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/5381694.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=5381694</wfw:commentRss><description>&lt;P&gt;Team Build is a build workflow tool. It manages how and when builds are performed. Currently (in VS2005 and VS2008), that workflow was written in the language of MSBuild. This allows us a lot of flexibility and power on the machine that runs the build. However, modifying the MS.TF.Build.Targets file that contained the description of the workflow was heavily discouraged and by no means easy. So, how can we make changing the workflow of the build easier. The first step (we believe) is to change the language that the workflow is described in. Windows Workflow is a natural choice. As we look at using Windows Workflow within Team Build, I will attempt to write some useful posts on things that we have discovered or realized.&amp;nbsp;Mostly things that the books don't talk about. This is my first attempt...&lt;/P&gt;
&lt;P&gt;First let me tell you about the books that I have read on WF. I read Bruce Bukovics' "Pro WF" first. This is a great starter for a developer wanting to write WF solutions. Bruce covers all of the functionality you would need to know. But, if you want to host WF and allow your users to manipulate the workflow directly, you need more details about how it works. The second and last book that I read on WF was "Essential Windows Workflow Foundation" by Dharma Shukla and Bob Schmidt. The Essentials book is really brief, but explains how WF Activities really work. If you plan on writing your own custom activities, this book is very useful.&lt;/P&gt;
&lt;P&gt;So, what did I learn. More importantly, what have I learned that I didn't get from the books. Well the first thing you should know is that you can represent a workflow in many different ways. The workflow is basically a tree of classes derived from Activity. There are two ways to represent the tree in the Visual Studio world: in code; and in XAML (basically XML). Workflow uses the extension XOML, however, to let VS know that its a workflow and not some kind of WPF stuff (more on WPF in another post). Working with code is the most natural way to deal with the Activity tree. In fact, even if you choose to create your workflow in XOML, VS will create a code behind file for you and compile your XOML into a dll.&lt;/P&gt;
&lt;P&gt;The first lesson we learned was... If you want to use XOML only and not do any code behind, you must create the XOML yourself or hand edit the XOML created by Visual Studio. When Visual Studio creates the XOML file, it assumes you will compile it. To compile XOML you need a special attribute on the root element in the XOML that tells the compiler to create a class. The attribute is "&lt;FONT color=#ff0000 size=2&gt;x:Class&lt;/FONT&gt;". If you create a XOML workflow in Visual Studio and open that XOML in the XML editor or in notepad, this should be the first attribute of the root element.&lt;/P&gt;
&lt;P&gt;When you load a workflow in the workflow runtime, there are two ways to do it. Call load with a type, this implies that the XOML or straight code workflow is compiled. Or you can call load with an xml reader, that has the XOML loaded. If you choose the xml reader option and that x:Class attribute is in the XOML, an error will be thrown by the runtime. However, if you try to compile XOML without that attribute, compilation will fail. So, the first choice you have to make in using XOML files is "To compile or not to compile" - that is the question ;)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5381694" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category><category domain="http://blogs.msdn.com/jpricket/archive/tags/Workflow/default.aspx">Workflow</category></item><item><title>TFS 2008 - Running two Build Agents on the Same Machine</title><link>http://blogs.msdn.com/jpricket/archive/2007/08/03/tfs-2008-running-two-build-agents-on-the-same-machine.aspx</link><pubDate>Fri, 03 Aug 2007 21:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4209832</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/4209832.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=4209832</wfw:commentRss><description>&lt;P&gt;There have been at least a couple of forum posts from users that would like to run more than one build agent on the same physical machine. The normal reason is that they have more than one TFS server and want to use the machine as a build agent for both.&lt;/P&gt;
&lt;P&gt;In this post I will describe how to add another build agent to a machine that already has one installed. The steps are very manual but should be simple enough.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;First you need to copy the actual binary for the service and it's config file. The config file is keyed off the name of the binary, and we have to have a separate config file for each.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;cd "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies"&lt;/LI&gt;
&lt;LI&gt;copy TfsBuildService.exe&amp;nbsp;TfsBuildService-2.exe&lt;/LI&gt;
&lt;LI&gt;copy TfsBuildService.exe.config TFSBuildService-2.exe.config&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;Next you need to edit the new config file to point to the other server and use a different port number.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;notepad TFSBuildService-2.exe.config&lt;/LI&gt;
&lt;LI&gt;Search for port and change the port number from 9191 to something new like 8181&lt;/LI&gt;
&lt;LI&gt;There's also another port number for interactive running that defaults to 9192, you should change that one as well. Let's say to 8182.&lt;/LI&gt;
&lt;LI&gt;Now, search for AllowedTeamServer and set the value to the full URL of the new server.&lt;/LI&gt;
&lt;LI&gt;Save your changes.&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;Now, you can install the new service using sc.exe and get it started.Take note of the spaces after the equals signs in the sc command line.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;sc &lt;A href="file://jpricket-test/" mce_href="file://jpricket-test/"&gt;\\jpricket-test&lt;/A&gt; create&amp;nbsp;"MyVSTFBuild" binPath= "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\TfsBuildService-2.exe" DisplayName= "My Team Build Service"&lt;/LI&gt;
&lt;LI&gt;Now, open up Control Panel\Administrative Tools\Services.&lt;/LI&gt;
&lt;LI&gt;Find "My Team Build Service". Right click on it and open&amp;nbsp;Properties.&lt;/LI&gt;
&lt;LI&gt;On the Log On tab, set it to the service account and password&amp;nbsp;that you want to use.&lt;/LI&gt;
&lt;LI&gt;Hit OK to save&amp;nbsp;your changes and then start the service.&amp;nbsp;&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;Finally, you have to create a build agent on the other server that points to this new machine and port.&lt;/LI&gt;
&lt;UL&gt;
&lt;LI&gt;Open Visual Studio&lt;/LI&gt;
&lt;LI&gt;Connect the other TFS server and the correct Team Project&lt;/LI&gt;
&lt;LI&gt;Right click on the Builds node in team explorer and select Manage Build Agents.&lt;/LI&gt;
&lt;LI&gt;Make sure to create one with the correct port number and machine name.&lt;/LI&gt;
&lt;LI&gt;You will also want to change the "Working Directory" to something different that the other instance of the build service uses. I used "$(Temp)\my\$(BuildDefinitionPath)"&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;&amp;nbsp;Now, you're ready to build on both agents using the same machine.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE:&lt;/STRONG&gt; I neglected to mention that you should reserve the new port number that you decide to use in step 2. You can read up on how to do this with the wcfHttpConfig tool&amp;nbsp;&lt;A class="" href="http://msdn2.microsoft.com/en-us/library/bb552291(VS.90).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/bb552291(VS.90).aspx"&gt;here&lt;/A&gt;. Basically you just need to run a command prompt, change to the privateassemblies area of the Visual Studio program directory (usually&amp;nbsp;C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies) and type the following at the command line:&amp;nbsp; &lt;EM&gt;wcfhttpconfig.exe reserve DOMAIN\TeamBuildAccount 8181&lt;/EM&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4209832" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Creating Fake builds in Orcas with IBuildDefinition.CreateManualBuild </title><link>http://blogs.msdn.com/jpricket/archive/2007/07/06/creating-fake-builds-in-orcas-with-ibuilddefinition-createmanualbuild.aspx</link><pubDate>Fri, 06 Jul 2007 18:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3730294</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/3730294.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=3730294</wfw:commentRss><description>&lt;P&gt;In my &lt;A class="" href="http://blogs.msdn.com/jpricket/archive/2007/05/21/adding-a-fake-build-to-the-team-build-server.aspx" mce_href="http://blogs.msdn.com/jpricket/archive/2007/05/21/adding-a-fake-build-to-the-team-build-server.aspx"&gt;last post about creating a Fake build&lt;/A&gt;, I gave you the code to create a fake build in V1 and I promised to give you the code to do the same thing in Orcas. So, here it is. This code won't work in Beta1 or Beta2, but should work as is when you get an RC or RTM version of Orcas. The CreateManualBuild API was added to the code base post Beta2 cutoff.&lt;/P&gt;
&lt;P&gt;So, here's the code:&lt;/P&gt;&lt;CODE&gt;&lt;PRE&gt;using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.Build.Proxy;
using Microsoft.TeamFoundation.Client;
using Common = Microsoft.TeamFoundation.Build.Common;
using Microsoft.TeamFoundation.Build.Client;

namespace AddFakeBuild
{
    class Program
    {
        static void Main(string[] args)
        {
            AddBuild("http://jpricket-test:8080", "jpricket-070507", "fakebuild23");
        }

        static void AddBuild(String serverName, String teamProject, String buildNumber)
        {
            // Get the TeamFoundation Server
            TeamFoundationServer tfs = new TeamFoundationServer(serverName);

            // Get the Build Server
            IBuildServer buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));

            // Create a fake definition (and agent)
            IBuildDefinition definition = AddDefinition(buildServer, teamProject, "FakeDefinition1");

            // Create the build detail object
            IBuildDetail buildDetail = definition.CreateManualBuild(buildNumber);

            // Create platform/flavor information against which test 
            // results can be published
            IConfigurationSummary confSummary = InformationNodeConverters.AddConfigurationSummary(buildDetail, "Debug", "x86", "");
            ICompilationSummary compSummary = confSummary.AddCompilationSummary();
            compSummary.ProjectFile = "Dummy.sln";
            compSummary.Save();

            // Complete the build by setting the status to succeeded and setting the drop location.
            buildDetail.Status = BuildStatus.Succeeded;
            // The drop location is not copied properly from the definition so we have to copy it manually.
            buildDetail.DropLocation = definition.DefaultDropLocation;
            buildDetail.Save();
        }

        private static IBuildDefinition AddDefinition(IBuildServer buildServer, string teamProject, string definitionName)
        {
            try
            {
                // See if it already exists, if so return it
                return buildServer.GetBuildDefinition(teamProject, definitionName);
            }
            catch (BuildDefinitionNotFoundException)
            {
                // no definition was found so continue on and try to create one
            }

            IBuildAgent agent = AddAgent(buildServer, teamProject, "FakeAgent1");

            IBuildDefinition definition = buildServer.CreateBuildDefinition(teamProject);
            definition.Name = definitionName;
            definition.ConfigurationFolderPath = "$/";
            definition.ContinuousIntegrationType = ContinuousIntegrationType.None;
            definition.DefaultBuildAgent = agent;
            definition.DefaultDropLocation = @"\\MySharedMachine\drops\";
            definition.Description = "Fake build definition used to create fake builds.";
            definition.Enabled = false;
            definition.Workspace.AddMapping("$/", "c:\\fake", WorkspaceMappingType.Map);
            definition.Save();

            return definition;
        }

        private static IBuildAgent AddAgent(IBuildServer buildServer, String teamProject, String agentName)
        {
            IBuildAgent agent = buildServer.CreateBuildAgent(teamProject);
            agent.Name = agentName;
            agent.BuildDirectory = "c:\\nobuilddir";
            agent.Description = "Fake build agent used to create fake builds.";
            agent.MachineName = "NoBuildMachine";
            agent.Port = 9191;
            agent.Status = AgentStatus.Disabled;
            agent.Save();

            return agent;
        }
    }
}&lt;/PRE&gt;&lt;/CODE&gt;
&lt;P mce_keep="true"&gt;There are a couple of things to take note of here. First, you may have noticed that I am creating a Build Definition and a Build Agent. In Orcas, if you try to create a Build without these things existing, you will get exceptions thrown from the server. However, if you were to use existing Definitions and Agents, the code gets a lot smaller. The next thing you should look closely at is the call to definition.CreateManualBuild. This new method encapsulates most of the code that we did in the V1 version.&lt;/P&gt;
&lt;P mce_keep="true"&gt;CreateManualBuild is located off the IBuildDefinition interface. This allows you to get all the definition defaults for free. There are several overloads for this call. The shortest is used here. It takes in a build number and defaults all the other values. If you really had a manual build that you had copied to a drop location, you could specify the drop location as the next parameter to this call. The long version allows you to specify buildNumber, dropLocation, buildStatus, agent, and requestedFor. &lt;/P&gt;
&lt;P mce_keep="true"&gt;In the above example code, the status of the build after calling CreateManualBuild is InProgress. I then add some project details to the build information and change the status to Succeeded. By setting the Build Status to a completed status myself, the BuildCompletion event is fired as if this was a real build. If the status was set to Succeeded in the CreateManualBuild call, the event would never be fired for this build. This gives you the ability to create historical builds (no events needed) or to create manual builds where you might want the events.&lt;/P&gt;
&lt;P mce_keep="true"&gt;I know many customers will find this new API very useful.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3730294" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Adding a Fake Build to the Team Build Server</title><link>http://blogs.msdn.com/jpricket/archive/2007/05/21/adding-a-fake-build-to-the-team-build-server.aspx</link><pubDate>Mon, 21 May 2007 17:58:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2768530</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/2768530.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=2768530</wfw:commentRss><description>&lt;P&gt;Why would anyone want to add a fake a build to the team build server? Well, there is one very big reason - Integration with Team System. If you don't use Team Build V1 to build your sources (for whatever reason), you may want to at least store some build information in the Team Build server. This allows you to publish test results, associate work items with builds, and view your build information from within Visual Studio.&lt;/P&gt;
&lt;P&gt;I saw an older post by someone else that had most of the code. Unfortunately, they were missing the line at the bottom that actually&amp;nbsp;Completes the build. Without this line you won't be able to associate work items with a build number. The code is commented and should be very straight forward. Note that in V1 this process requires several Web Service calls not just one.&lt;/P&gt;
&lt;P&gt;So, here is the code:&lt;/P&gt;&lt;CODE&gt;&lt;PRE&gt;using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.TeamFoundation.Build.Proxy;
using Microsoft.TeamFoundation.Client;
using Common = Microsoft.TeamFoundation.Build.Common;

namespace AddFakeBuild
{
    class Program
    {
        static void Main(string[] args)
        {
            AddBuild("http://TeamBuildRTMSP1:8080", "MsfAgile", "FakeBuild001");
        }

        static void AddBuild(String serverName, String teamProject, String buildNumber)
        {
            // Get the TeamFoundation Server
            TeamFoundationServer tfs = new TeamFoundationServer(serverName);

            //Construct build store and build controller objects
            BuildStore bStore = (BuildStore)tfs.GetService(typeof(BuildStore));
            BuildController bController = (BuildController)tfs.GetService(typeof(BuildController));

            //Create a build entry
            BuildData bd = new BuildData();

            //Fill in mandatory information for BuildData object
            bd.BuildNumber = buildNumber;
            bd.BuildType = "DummyBuildType";
            bd.TeamProject = teamProject;

            // Make sure that this drop location exists, otherwise 
            // test publish will fail
            bd.DropLocation = @"\\MySharedMachine\drops\" + buildNumber;
            bd.BuildMachine = "NoBuildMachine";
            bd.RequestedBy = Environment.UserName;

            // These string values are locale dependent in V1
            bd.BuildStatus = Common.BuildConstants.BuildStatus.BuildSucceeded;
            bd.BuildQuality = "Not Examined";

            // Add build entry to TeamBuild DB
            bStore.AddBuild(teamProject, bd);

            // Get the URI of the build
            string buildUri = bStore.GetBuildUri(teamProject, buildNumber);

            // Create platform/flavor information against which the test 
            // results will be published
            ProjectData pd = new ProjectData();

            // Fill in mandatory information for ProjectData object
            pd.FlavourName = "Debug";
            pd.PlatformName = "x86";
            pd.ProjectFile = "Dummy.sln";

            // Add project data entry for this build.
            bStore.AddProjectDetailsForBuild(buildUri, pd);

            // Fill in the finish time
            bStore.UpdateBuildFinishTime(buildUri, DateTime.Now);

            // Complete the build and fire the BuildCompletion Event
            bController.BuildCompleted(buildUri);
        }
    }
}
&lt;/PRE&gt;&lt;/CODE&gt;
&lt;P&gt;In my next post, I will show you how to do this in Orcas!&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2768530" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Visual Studio 2005 Client starting builds on an Orcas server and build machine</title><link>http://blogs.msdn.com/jpricket/archive/2007/05/16/visual-studio-2005-client-starting-builds-on-an-orcas-server-and-build-machine.aspx</link><pubDate>Wed, 16 May 2007 15:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2671860</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/2671860.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=2671860</wfw:commentRss><description>&lt;P&gt;One of the problems that we are seeing pop up internally is with groups that for whatever reason have not upgraded their clients to Orcas, but are starting builds with VS 2005 clients on an Orcas server. This scenario is completely supported, but they seem to be running into one main problem.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Problem:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: red"&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;TF215036: The build request cannot be queued at or below position 1 on agent \tp\agent1. The resulting position would be 2.&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Reason:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;That error message is given to a V1 client trying to start a build when there is already a build in the Queue. In V1 we didn't have a queue, so for V1 to work correctly, when we get a Start Build call from the V1 web service we throw an error unless the build can be started right away. But why is there one in the Queue? What seems to typically happen is that at some point the Build Agent is rebooted or shut down for some period of time. During the shutdown, a build is started. Since the agent is unreachable by the server, the server errors out the build and marks the agent as unreachable. The next build that is started is Queued, but never actually runs, because the server doesn't retry starting a build on an agent that is unreachable. Now, the V1 client is stuck in limbo. There is no way to see the Queue or cancel that build and starting another build just errors out.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Solution:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;The easiest solution is to connect to the server with an Orcas client, open up the Manage Build Agents dialog, open the Agent in question and set the status to enabled. This should cause the Queued build to start right away. Once the Queue is cleared, starting builds should work as expected.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2671860" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Build Type BuildDirectoryPath =&gt; Build Agent Working Directory</title><link>http://blogs.msdn.com/jpricket/archive/2007/04/30/build-type-builddirectorypath-build-agent-working-directory.aspx</link><pubDate>Mon, 30 Apr 2007 16:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2340059</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/2340059.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=2340059</wfw:commentRss><description>&lt;P&gt;In Team Build version 1, all information about how to perform the build was stored in the Build Type, which was basically a folder that contained the TfsBuild.proj file, the WorkspaceMapping.xml file, and the TfsBuild.rsp file. In the Orcas release, we have divided the information up so that some of it now resides in the Team Build database. One of the pieces of information that moved to the database is the build location (now called the working directory). &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;A Change in Location and Usability&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In version 1, the user could override the build location when starting a build. In Orcas, the user can't do that. The build location (working directory) is part of the information associated with the Build Agent and can only be changed on the Build Agent Properties dialog. Why, you may ask? As we move towards a model where the user doesn't pick the actual machine that the build runs on (not there yet in Orcas), it is important to keep the details of how the build will actually be performed, tucked away in a safe place. For example, what if the user expected the build agent to have a d: drive and used that as the build location. The build would succeed on some machines but would fail on any that didn't have a d: drive. Assuming that the build machines are maintained by a central IT group (or perhaps the one IT guy), it is much easier for that group to also maintain the build agent information like the working directory. By centrally locating this information and keeping it out of the hands of the average user, we hope to avoid needless build breaks.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Fixing the Problems&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;One of the problems that some users encountered in version 1 was that the directory structure under the build location root was too long. There is a limit of 260 characters in any path. The real problem is that the user couldn't change anything but the root of the directory structure. Setting the build location to "d:\BL" still produced a path like "d:\BL\TeamProject\TypeName\Sources" as the root of the workspace. In some cases, this was just too long when appended with the longest workspace path. To help fix this problem in Orcas, we now allow the user to specify most of the working directory path. And you can use environment variables as well! The default working directory is "$(Temp)\$(BuildDefinitionPath)" which ends up being something like "C:\DOCUME~1\jpricket\LOCALS~1\Temp\TeamProject\daily\". On to the end of this root we still add "Sources". If that's too long, you can change it to a hard coded path. But we recommend that you make the path unique for each Build Definition. To do that in the shortest space possible, we have provided $(BuildDefinitionId) which you can use in place of $(BuildDefinitionPath). Both of these values are unique for each build definition in the database. For example, a working directory of "d:\BL\$(BuildDefinitionId)" would produce a root folder something like "d:\BL\1245\Sources". By giving you control of this path, we hope to solve the problems associated with long paths in source control.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Structure Under the Root&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In V1 the structure under the build location was something like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;c:\BuildLocation\TeamProject\TypeName\&lt;STRONG&gt;Binaries&lt;/STRONG&gt; - The Output Directory for MSBuild is overridden so that all the outputs of the build process are put under this folder.&lt;BR&gt;c:\BuildLocation\TeamProject\TypeName\&lt;STRONG&gt;BuildType&lt;/STRONG&gt; - The build type information is downloaded here.&lt;BR&gt;c:\BuildLocation\TeamProject\TypeName\&lt;STRONG&gt;Sources&lt;/STRONG&gt; - The root of the workspace is mapped to this folder.&lt;BR&gt;c:\BuildLocation\TeamProject\TypeName\&lt;STRONG&gt;TestResults&lt;/STRONG&gt; - The results of the test runs are placed in this folder.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In Orcas, we have maintained this same structure by default, but you can change it! In TfsBuildService.exe.config file, there are keys for each one of the above subfolders that can be overriden. The only real reason to do this is to shorten the names of these folders to avoid the 260 character limit on paths.&amp;nbsp;Keep in mind, that this entire structure only serves as a working area for MSBuild. When the compilation and tests are done, all of the important files like the Binaries, Test Results, and build log are copied to the Drop Location share. Then this space can be reused by the next build.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2340059" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category></item><item><title>Queuing a build in PowerShell</title><link>http://blogs.msdn.com/jpricket/archive/2007/04/25/queuing-a-build-in-powershell.aspx</link><pubDate>Wed, 25 Apr 2007 16:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2272806</guid><dc:creator>Jason Prickett</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jpricket/comments/2272806.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jpricket/commentrss.aspx?PostID=2272806</wfw:commentRss><description>&lt;P&gt;I just read Aaron's post &lt;A class="" href="http://blogs.msdn.com/aaronhallberg/archive/2007/04/24/team-build-object-model-queueing-a-build.aspx" mce_href="http://blogs.msdn.com/aaronhallberg/archive/2007/04/24/team-build-object-model-queueing-a-build.aspx"&gt;"Team Build Object Model - Queueing a Build"&lt;/A&gt; and I just had convert his code to PowerShell (for those of us that just hate waiting for code to compile!). &lt;/P&gt;
&lt;P&gt;So, here is how to Queue a build in PowerShell (uses my Get-BuildServer script found &lt;A class="" href="http://blogs.msdn.com/jpricket/archive/2007/03/29/various-powershell-scripts.aspx" mce_href="http://blogs.msdn.com/jpricket/archive/2007/03/29/various-powershell-scripts.aspx"&gt;here&lt;/A&gt;):&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&amp;gt; $buildserver = Get-BuildServer "&lt;A href="http://tfs:8080/"&gt;http://tfs:8080&lt;/A&gt;"&lt;BR&gt;&amp;gt; $teamProject = "TeamProject"&lt;BR&gt;&amp;gt; $buildDefinition = "Nightly"&lt;BR&gt;&amp;gt; $definition = $buildserver.GetBuildDefinition($teamProject, $buildDefinition)&lt;BR&gt;&amp;gt; $request = $definition.CreateBuildRequest()&lt;BR&gt;&amp;gt; $buildserver.QueueBuild($request, "None")&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As you can see the code is almost identical (minus the great comments that Aaron's code has). The benefit that I see to doing this in PowerShell is simply that you don't have to open VS, create a new project, write the code, compile it, open the bin folder, and then run the exe. Instead, you can simply open PS, type the code, and see the results.&lt;/P&gt;
&lt;P&gt;Look for more PowerShell scripts coming soon like Queue-Build.ps1!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2272806" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jpricket/archive/tags/Team+Build/default.aspx">Team Build</category><category domain="http://blogs.msdn.com/jpricket/archive/tags/PowerShell/default.aspx">PowerShell</category></item></channel></rss>