Tuesday, May 22, 2012

Community TFS Build Manager – Change Drop Location Preview

A couple of weeks ago I was faced with a sudden replacement of the server hosting the drop file share for a collection hosting 150+ builds. Even though it didn’t’ please some of the builds admins, I remained calm and promised them I could easily change drop locations for all builds with the Community TFS Build Manger. I was quite sure the Build Manager had a feature to batch change the drop location of selected builds.

But I was wrong
Much to my surprise I couldn’t find any way to change the drop location using the Community Build Manager.  I can say I looked for more than a while, as I was quite sure it was possible, but at last I had to surrender to the state that it wasn’t possible using tfs build manager.  Somehow I must have mixed up the feature set with my own hacks or simply assumed it would be included. 

No need to panic  ;)
I knew I had implemeted a similuar feature a long time ago, After a short diging I found what I was looking for. I had implemented a Change Drop Location feature back in 2009 in a tool/hack TfsBuildAdmin and I could probably use it or rewrite it again. It turned out that the 2009 TfsBuildAdmin tool was against the old build API and I had already rewritten the Change Drop Location feature against the new tfs2010 build API. This meant that I had a solution to batch update 150 build drop locations. First problem solved!

A promise is a promise
But I still had a problem; I kind of had promised that the Change Drop Location feature was included in the Community TFS build Manger. And of course it would be best to have such features integrated in a common tool like Build Manager.  So I simply emailed Jakob Ehn and Michael Fourie and described the problem, the solution and offered to assist in developing the feature set.

Build Manager Change Drop Location feature
This is the result so far, then selecting (multiple) builds and right clicking you get a new menu item Change Drop Location. Once selected it presents you a form to select update method. You can do both search and Replace updates and force a standard drop location for all build definitions using a couple of macros such as $(TeamProject)  and $(BuildServer)
You also have an option to update drop locations for existing builds (to ensure that the link in the build reports works for existing or old builds)

Preview download available
If you can’t wait until the next release of Tfs Community Build Manager I have put together a preview of the standalone application with the Change Drop Location feature enabled. You can download it from my SkyDrive https://skydrive.live.com/?cid=5d46cae8c0008cf0&resid=5D46CAE8C0008CF0!1052&id=5D46CAE8C0008CF0!1052

Update 2012-06-02 This code is now committed to the main branch for Tfs Build Community extensions and can be downloaded and built using the following changeset http://tfsbuildextensions.codeplex.com/SourceControl/changeset/changes/76886.

Monday, May 14, 2012

Test Attachments Sizes: New feature of TFS Administrators Toolkit

If you have experienced rapid growth of your tfs database size you have hopefully aware of the Test Attachments Cleaner Power tool. If you have used it you probably also noticed that it’s easier to do the cleaning then to find out what’s needs cleaning.

Test Attachments Power tool – Missing pieces
The problem is that you need to know what team project that needs cleaning and what kinds of attachment it has. There are a couple of posts out there with SQL to run against the TFS Production databases, which by the way is not supported.  Once you know what projects to clean and what the attachments data consist of, you can create a command line that calls the test attachments cleaner power tool to do the cleaning.
If you have about 100+ team projects to handle this is far from the best experience. What you really would like is an easy way to:
1)    Find team projects with large attachment sizes.
2)    Analyze the structure of test attachment data.
3)    Select action and kick of the test attachment cleaner power tool.

Test Attachment Sizes window in Tfs Administrators Toolkit
As I manage a couple tfs servers with 100+ team projects I decided to try to fill the gap. The result of my effort is the new Test Attachment Sizes window in Tfs Administrators Toolkit.  It gives you the following features:
•    Breakdown of totals Test Attachments sizes by type and extensions.
•    A sortable list with team project and its total test attachment size
•    Breakdown of team project test attachments by type and extensions
•    Selecting action and calling Test Attachment Cleaner power tool, either direct or generating a bat file

I’ve released an updated version of the Tfs Administrators Toolkit with the new Test Attachments Sizes feature along with some minor fixes at http://visualstudiogallery.msdn.microsoft.com/11f5e313-ced1-4713-9794-d7300c7d12e0

Saturday, May 5, 2012

Generate accumulated Release Notes in TFS build

Have you ever wanted to have the build process generate an automated generated release notes document for all changes accumulated form the last release? This is how you can do it with Tfs Build Extensions.

The plan 
 The plan is simple, Let the user set a baseline label name in the build definition, get a list of changesets by comparing the baseline label with the current build label. From the list of changesets get comments, Associated Work items and changed files. With the list of changesets and work items it should be possible to generate a Release Notes document.
Now all we need to do is code this, or even better reuse something existing. Now, if you’re trying to do something within build automation, and you would need to write your own custom activities you should probably start by looking at the Community TFS build extensions project at codeplex, before you start coding.

TFS Build extensions BuildReport and CompareLabels activities
A fast look at the list of activities in the shows two interesting candidates, there is both a CompareLabels and an BuildReport activity.
Looking a bit closer, the CompareLabels activity takes two Labels and generates a list of changesets and the BuildReport activity takes a list of changesets and generates a build report in .html or .txt and you can customize the generated report by applying your own xslt transformation fie.
This is about everything we need and we should hopefully only need to drag the activities into our build process workflow and make sure we pass the output list of changesets from the CompareLabels activity to the BuildReport input parameter.

The hiccups
Putting the plan to work, we soon run into to trouble, to start with the CompareLabels activity doesn’t takes label names as input as one might hope for, instead it requires VersionControlLabel objects, and on top of that it also needs a VersionControlServer object.
At first, this may be discouraging, but it isn’t such a big problem as we can use the tfs api directly inside the build workflow, and if we manage to get an VersionControlServer we could use it to get a the VersionControlLabel objects by using the QueryLabels method of VersionControlServer.

Getting a VersionControlServer
First we need to get an instance of a VersionControlServer, so we start by declaring it as a variable. The VersionControlServer is created by calling GetService() of a tfsTeamProjectCollection object. If we have the Uri of the teamprojectcollection we can create it by specifying it in the constructor. We can get the Uri for the current collection from the BuildDetail object we have in our build. Putting it all together in (vb.net) results in this expression

          , VersionControlServer)

Getting the VersionControlLabel for a label name
Once we got the scSrv we can use the QueryLabels method to get our VersionControlLabel objects from the LabelName. We have the current label in BuildDetail.BuildLabelName, but it expressed as Labelnamne@sourcecontrolpath. What we need to pass into the QueryLabel is label name and source control path in different variables.
We need to split the string into two separate strings (currentLabelName and sourcecontrolPath)  by using the split method as follow.

currentLabelName = BuildDetail.LabelName.Split(New Char() {"@"c})(0)
labelSrcPath     = BuildDetail.LabelName.Split(New Char() {"@"c})(1)

Now we can call QueryLabel to get the VersionControlLabel objecs,

scSrv.QueryLabels(currentLabelName , labelSCPath, Nothing, False)(0)
scSrv.QueryLabels(BuildReportFromBuildLabel, labelSCPath, Nothing, False)(0)

Stitching it together 
Now we got everything figured out, now we just need to complement our sequence with a couple of assigns to get the VersionControlServer and splitting the labelstring.
We also got to change the properties of the CompareLabels activity to use QueryLabel method.
Proprties for CompareLabels activity

Running this could be a bit noisy in the build log, so to make it a bit more silent, we can manully editing the xaml file and add

mtbwt:BuildTrackingParticipant.Importance="None" to each activity we want to exlude the output from.

We also need to declare the input  baseline label name as an build argument and make it visible in the edit build definition form. This is done by fist adding a build argument like this:

To make it visible in the builddefinition editor we need add metadata for the build argument, this is done by locating the Metadata argument and clicking the edit button. We simply add an item for our baseline build label and selects the desired visibility in the View this parameter when dropdown. To make it visible in the build defninition editor select Only while editing a definition

The result  
Before we run the build we need to specify the label name of the last release, so that we can get all changes after that label into our release document. 
Running the build will generate a ReleaseNotes.txt, a RelaseNote.html and a ReleaseNotes.xml file in the root of the drop folder. This document is rather changesets oriented, but by supplying our own xslt file we should be able to turn the release document into a list of work items, and if we like list all changesets with comments.