Tuesday, 8 October 2013

Structuring Visual Studio Solutions and hooking into your Visual Studio’s build process.

This is the first of a series of posts I will write about a very common problem faced by all sizable projects – how to structure your visual studio projects and resolve inter-dependencies between projects in different visual studio solutions. This is not an issue if you have just one visual studio solution as you can use project references across the board. However, if you have a number of solutions and there a developers working on them simultaneously than the dependencies can sometimes be crippling.

From my experience, the following structure is quite common for most projects.


The Platform Service solution contains common platform specific libraries like configuration, diagnostics, common controls, etc. The Domain Specific services contain libraries specific to the business domain such for example business specific libraries, protocols or schemas. Then there are vertical solutions on top.

In terms of visual studio solutions and project dependences, I would create a solution for each layer and the visual studio projects sitting in top layers are dependent upon projects in the lower layers.

Now that I have explained the context, let’s see different options we have in terms of setting up projects etc. The first and most common method is to set up a “DevBuild” i.e. a build  script that builds all solutions in the order starting from the lower level solutions and culminating with compiling all the “verticals”.

All references within a solution are project references and references across solutions are file references. It’s best practice to reference the assemblies from a common “Assemblies” folder rather than the output path. Typically, you would want to do the copying of all assemblies after a build as a post-build activity. There are different ways of doing it. Below are some of the ones that I have used

1) Adding a custom .targets file in the within the $(MSBuildToolsPath)\Microsoft.Common.Targets\ directory.

This is my favourite and provides a clean “extension” point to add to the Visual Studio Build process. Visual Studio adds two folders within the MSBuild installation directory (C:\Program Files(x86)\MSBuild\12.0 for Visual Studio 2013). Within the directory, there are folders called ImportBefore and ImportAfter. You can write your own MSBuild code and store the file in either of the two folders. If you have extended or hooked into one of the targets run by Visual Studio as part of building a solution, your code will be executed. For example, the following code copies all the assemblies that starts with the name MyCustom and drops them to the common assemblies location for where they can be referenced by other solutions.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="
    <Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
        <DevelopmentRoot Condition="$(DevelopmentRoot) == ''">C:\Projects\MyCustom\Development\Main</DevelopmentRoot>
    <Target Name="CopyAssemblies" AfterTargets="Build" Condition="'$(SkipCopyAssemblies)' != 'true'">            
            <NetFilesToCopy Include="$(MSBuildProjectDirectory)\**\bin\$(Configuration)\MyCustom*.dll"/>
        <MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="RemoveDuplicateFiles" InputItems1="@(NetFilesToCopy)" Condition="%(NetFilesToCopy.Identity) != ''">
            <Output TaskParameter="OutputItems" ItemName="NetFilesToCopyUnique"/>
        <MakeDir Condition="!Exists($(AssembliesDirectory))" Directories="$(AssembliesDirectory)"/>
        <Microsoft.Build.Tasks.Copy SourceFiles="@(NetFilesToCopyUnique)" DestinationFolder="$(AssembliesDirectory)" Condition="%(NetFilesToCopyUnique.Identity) != ''"/>       


2) Using Post Build Event command

The post build events have been around since early releases of Visual Studio and allows you to run custom macros at the end of the build process. For me these are rather messy and interfere with your build process especially if you are using Team Build.

3) Visual Studio Add-on

Again a very messy approach but something we have used in the past. You can write your visual studio add-on that traps the compilation event and perform tasks such as copying files to a pre-defined location. I wouldn’t recommend it.

4) Use Visual Studio Solution extension points

When you build a visual studio solutions, behind the scenes, it generates and MSBuild file and uses the generated MSBuild file. In the generated MSBuild file, it includes two files called after.<SolutionName>.sln.targets and before.<SolutionName.sln.targets. If you have files with those names in the same directory and your solution files, it will become part of the build process and provides you an extension point. Sayed Ibrahim Hashimi has detailed it here.

The downside is that the extension points are only used when MSBUILD is called on the solution file (.sln) file from command line. Visual Studio doesn’t support it yet as detailed here.

For me Option 1 is still the best approach if you decide to go down the DevBuld route.

In my next post, I will write about NuGet and how it can be used as an alternative.

Technorati Tags: ,

Wednesday, 2 October 2013

Building Visual Studio 2013 solutions with your TFS 2010 / 2012 Build Templates

Visual Studio 2013 is shipped with a new version of MSBuild. The new version or MsBuild 12.0 contains a number of new features as described here. It is installed separately and from now onwards will be following Visual Studio release cycle rather than .Net Framework’s release cycle.

If you are using Visual Studio 2013 to build say a Windows 8.1 app and are still using your TFS 2010 or TSF 2012 build templates, you might get errors because by default the templates use MSBuild 4.0. To resolve the issue please edit your build templates to do the following

1) Find all instances of the MSBuild activity. The activity is named as “Run MSBuild for Project” within the build templates as shown below

Run MSBuild Activity

2) Change the ToolsPath of the activity to point to the MSBuild 12.0 exe file as shown below

Run MSBuild ToolsPath

The TFS2013 version of this activity (Microsoft.TeamFoundation.Build.Workflow.Activities.MSbuild) contains a “ToolsVersion” property that you can use to set the correct version number but in earlier versions (such as TFS2010 or TFS2012) you will have to resort to pointing to the file location.

Implementing Static Code Analysis with StyleCop

In the Oct 2013 edition of MSDN Magazine I have written about details of how to set up StyleCop to run it in Team builds. The article can be found here

Thursday, 12 September 2013

BuildStepDuration activity - TFS Build Extensions

The September 2013 release of TFS Build Extensions is available for download now. There are some cool new activities added to the library. Amongst them is the BuildStepDuration activity. It is a very simple to use activity that allows you to view a break down of build steps and the time each build step took in a completed build. This is really useful for build masters who are looking to optimise their build and are having a hard time in getting the information from Visual Studio build details window, which shows all information in a hierarchical way.

More information can be read from the activity documentation http://bit.ly/15VuILe.

The latest version of TFS Build Extensions can be downloaded from here.

Thursday, 22 August 2013

Adding Custom Summary Section from your C# activity

Amongst the new activities shipped with Team Foundation Server 2012, I have found the WriteCustomSummaryInformation activity to be very useful. It is a very simple activity with only four properties and can be dragged and dropped anywhere into your build process template to create a custom summary section or write to an existing summary section. There is a good post about using this activity on MSDN.

However, if you are writing your own activity and need to write to the build’s summary, the activity is not really useful. In this blog post, I will demonstrate how to write to the build summary from within custom activity activity. The class that enables you to write to the build summary area is “CustomSummaryInformation” and it is present in the Microsoft.TeamFoundation.Build.Workflow.dll assembly. In order to inform the team build to register the custom summery information, you would need to call the Track method of the CodeActivityContext class as demonstrated below

   1:  private void WriteSummaryInformation(string key, int priority, string heading, string message)
   2:  {
   3:          this.ActivityContext.Track(new CustomSummaryInformation() 
   4:                                  {
   5:                                      SectionPriority = priority,
   6:                                      Message = message,
   7:                                      SectionHeader = heading,
   8:                                      SectionName = key
   9:                                  });
  10:  }

As, you can see, writing to the build summary is as simple as creating a new CustomSummaryInformation and tracking it with the activity context. TFS Build has a custom tracking participant with functionality to track objects of types such as BuildError, BuildInformationRecord, BuildMessage, etc. In fact, there are extension methods present to track types BuildError, BuildMessage and BuildWarning. There are not such extension methods available yet for CustomSummaryInformation.

Thursday, 18 July 2013

Uploading files to an ftp site from your Team Build

The July release of TFS Build Extensions were released yesterday. Amongst other improvements and features there library not contains an FTP Activity that allows the team build to interact with an FTP. You can for instance upload the contents of your drop location to an Ftp Site. This blog post details how to do so.

To use the Ftp activity activity, simply drag and drop it on the build process template. Once dropped, set the appropriate values for the properties required and if all the information is correct, the activity will be able to do the required task on your ftp server. Regardless of the ftp action, the following two properties are required and must be set
  • Action: Must be set to one possible values of FTPAction enumeration.
  • Host: Must be set to the host name of the ftp site.
To illustrate the use of the activity, we take a a very simple scenario that all files produced by the team build should be uploaded to an ftp site. Moreover, we also require that the files of each build should be created in a separate directory.

To start with, we need to take drop a sequence activity at an appropriate location in the build template. I chose to do it just above the “Check In Gated Changes for CheckInShelveset Builds”.


The next step is to drop the activities to find files, create directory and upload files. My final “Upload Drop Files to Ftp” looks as follows


Note that in the workflow I am using the FindMatchingFile activity, which looks for all files in the drop location and put the result in a variable “DropFiles”,  of type IEnumarable<string>.
Next the workflow checks if there are any files in the drops folder, if there are it will
First create a directory on the FTP site using the Ftp activity with action “FtpAction.CreateDirectory” using the name of the build. The value of all properties for this activity are shown below


The last step is to upload all files. The workflow has another FTP activity with action set to “FtpAction.UploadFiles”, passing in the enumeration “DropFiles”. The value of all properties of this activity are shown below.


And that is it. At the end of the sequence execution everything in the root of drop folder will be uploaded to the Ftp site provided.

Running the Activity
When your run the build workflow, you should see the Ftp activity being executed and the files in the drop location being uploaded to the ftp directory.

Saturday, 13 July 2013

Team Build Customisation - Running StyleCop on a Hosted Build Controller

For companies and individuals who don't or can't use an on premise version of Team Foundation Server, the hosted TFS service http://tfs.visualstudio.com is a great alternative. Once signed up, you can connect to the hosted version from visual studio just as you would connect to an on premise version and it provides the same if not a better experience.

However, when it comes to Team Builds, there is some restrictions on the type of customisation that you can do on your hosted build controller. You can, of course, create your own Build Machine and connect with the tfs.visualstudio.com service, but here we are looking a purely hosted service.

In this post, I will demonstrate how to customise your TFS build template to run StyleCop on all your code files. We will use the StyleCop activity present in TFS Build Extensions.

The first step is to get the two libraries need for customisation
1. StyleCop (http://stylecop.codeplex.com/). The version I am using is
2. Community TFS Build Extensions  (http://tfsbuildextensions.codeplex.com/). The version I am using is January 2013 release.

Changes in Build Controller
The first thing you need to do is to make your build controller aware of the location of the custom assemblies. This is the place from where the build controller will load assemblies to load and execute activities while running team build. To do so create a folder in your team project where you would want to keep all the build assemblies. Typically, I keep it separate from the project's main branch and other branches. The next step is to inform build controller of this location. For this

  1. Click on the build link in your team explorer window. Then click Actions and select Manage Build Controllers.

2. The following dialog appears. Select "Hosted Build Controller" and click on the properties button.

3. In the Build Controller properties dialog, set the "version control path to custom assemblies" property to the folder in team project that you created earlier

Click Ok and close the properties dialog. At this point, the build controller is configured to load your custom activities. The next step is to customise your build's template.

Custom Build Templates
When you create a team project, a folder called BuildProcessTemplate is created by default containing a number of build templates.

Its best practice to make a copy of the template before modifying it. I copied the file DefaulitTemplate.11.1.xaml and renamed it to CustomTemplate.xaml. This will be our custom build template. If you double click this file, you will see the team build workflow. 

The next step is to add the custom StyleCop Activity to this workflow. To do so you will need to do the following

1. Create a Workflow activity project in Visual Studio. This will create a project with all the assemblies required to create a workflow already added in the reference.

2. Add reference to the libraries StyleCop.dll, TfsBuildExtensions.Activities.dll and TfsBuildExntesions.StyleCop.dll

3. Add a link to the CustomTemplate.xaml to the project. Do to so, right click on the project, click Add and then Existing Item, browse to the file CustomTemplate.xaml, click on the arrow with Add button and select Add as Link. 

4.  The fourth and final step of setting up your environment to be able to modify custom template is to add the activities of TFS Build Extensions to the toolbox. To do so, first double click on your CustomTemplate.xaml file to load it up. In the Toolbox window, right click on the area below activities and select the option Add Tab. Name the new tab "TFS Build Extensions". Right click on the tab name and select choose items. Browse to the assemblies "TfsBuildExtensions.Activities.dll" and "TfsBuildExtensions.Activities.Stylecop.dll". The activities are loaded up on Toolbox and you are ready to add the StyleCop activity.

5.  Where do you want to run style cop in your build process is a matter for you decide. I typically want to do it first thing before anything gets compiled. So, I do it as part of "Initialize Variables" sequence in the workflow. I dragged a sequence activity at the end of it and named it "Run StyleCop" as shown.

 6. My Run StyleCop Activity looks like following

As you can see, in the sequence after using the usual write build messages, I use the activity FindMatchingFiles looking for all c# files. The activity properties are set as follows

Note that I am looking for all .cs files and storing the result in a variable called "SourceFilesToStylecop", which takes the type IEnumerable. "Execute StyleCop" is the "Community TFS Build Extension activity" and it's properties are set as following

This completes our changes to the CustomTemplate.xaml file. Save it and check it in.

Adding required assemblies to TFS
At this stage, our custom build template is all ready to be used. But before running it, we need to make sure that the custom assemblies and any related files are added to the TFS folder which was set in the  "Version control path to custom assemblies" option for our build controller. In this case, the assemblies we would want to load are the TFS build extension assemblies, StyleCop assemblies and it's dictionary and settings file. My custom assemblies folder look as follows.

Now, we are all ready to use our custom build template.

Using Custom Template in Build Definition
Open your build definition, click on process, expand Build Process Template and click on New button.

In the New Process Template dialog, select the option "Select an existing XAML file" and browse to the CustomTemplate.xaml file checked-in earlier. Click OK

Now your custom build is ready to be used. Run a sample build and you would see StyleCop being executed in your build doing static code analysis.

Wednesday, 26 June 2013

Are my changes in the release?

One question often asked from a release manager is "Are my changes in the release". This happens often especially when it comes to the crunch i.e. near the release deadline or at times of sending a patch to fix of a urgent high priority issue.

Team Foundation Server behaves slightly differently in selecting changesets to include in the build based on the build trigger. So, if you are pondering that a changeset you were not expecting in the build is not part of it, it might be useful to look at the build trigger option.

There are 5 options to trigger a team build and here is how changesets are chosen in each build case:

As named, the build with a manual trigger option will only occur a user queues a build manually. For builds triggered manually the executing build will fetch all the changes in the Active working folders until the point of time when the build fetches source files.

For example, let's say that the build was queued at 8:45 am but remained in the queue for 10 minutes So it started running at 8:55 am. Meanwhile, a couple of changes (changesets 11495 and 11497) were checked in at 8:47 am and 8:51 am respectively. The build would include both the changesets.

Continuous Integration :
If this trigger is selected, a build is queued every time a changeset is checked in. In this case, the build request also contains the changeset number that queued the build. For all CI builds, all changes in the Active working folder up to the changeset that queued the build would be in included in the build.

For example, if the build was queued at 8:45 am by a changeset 11495 and remained in the queue for 10 minutes i.e. it started running at 8:55 am. Meanwhile, another changeset 11497 was checked-in at 8:47 am. Another build was triggered. The first build would not include the changes present in the changeset 11497 even though the changes were already in source control at the time when the build was fetching source files.

Rolling Build:
With this trigger option, Team Foundation Server still triggers a build on a check-in but only if there are no build already in the queue or in progress. If a build is already in queue or in progress, it accumulates all changes and queues a new build once the first build is completed.6

Similar to Continuous Integration, the build request contains the changeset that queued the build and all changes up to that build number are included in the build.

For example, if the build was queued at 8:45 am by a changeset 11495 and remained in the queue for 10 minutes i.e. it started building at 8:55 am. Meanwhile, two changesets 11497 and 11498 were checked in checked-in at 8:47 am and 8:51 am respectively. Another build would be triggered after the first one is completed. The first build would not include changes in the changesets 11497 and 11498 even though the changes were in source control at the time when the build fetch source files.

Gated Check-in
With Gated check-in, a build is triggered for each changeset and only committed or check-in once the build is successful. With this option a build is queued for each changeset (assuming the option to merge and build gated builds is not selected).

Like Continuous integration, every build request has a changeset that triggered the build. However, unlike CI the build will include all changes which are check-in until the build fetches the source control and not when the build was queued.

For example, if the build was queued at 8:45 am by a changeset 11495 and remained in the queue for 10 minutes i.e. it started running at 8:55 am. Meanwhile, another changeset 11497 was checked-in at 8:47 am. Another build was triggered. The first build did not include changes in the changeset 11497 since they are checked-in yet. However, the second build did include changes checked-in as a result of the successful completion of previous build even though at the time of queuing the build these changes were not checked-in.

The scheduled build is triggered repeatedly on a particular day / time. For scheduled builds, TFS picks up all the changesets until the time when the build was queued.

For example, let's say that the build was queued at 8:45 am but remained in the queue for 10 minutes and start started running at 8:55 am. A couple of changesets 11495 and 11497 were checked in at 8:47 am and 8:51 am respectively. The build would NOT include both the changesets.

PS: To read more about the build triggers and the scenarios and the optimal scenarios to use them, read the Build Customization Guide produced by Microsoft ALM rangers.

Tuesday, 18 June 2013

TFS 2012 - Invalid Changesets appearing in the list of merges

I encountered this problem of getting unnecessary changesets in the merge list after branching using TFS 2012, so thought to blog about it.

I took a branch out of our main development branch, using the option "latest version". Immediately after the branch had been taken, I attempted to merge from the source branch to the newly created branch with the option of "selected changesets to merge". 

Since, nothing had been checked-in in the source branch, you would expect that the list is empty. However, I could see quite a few pending changes in there. Confused and somewhat unsure of what happened there, I did a folder comparison between the source and target branches and the files were in fact the same, so no concerns as far as branching goes.

This is actually a known issue in TFS 2012 and has been fixed in TFS 2012 Update 2. The issue was that if the source branch contains a file such that the file has had a case only rename (e.g. it has been changed from file.txt to File.txt), any changesets containing that particular file will still be shown in the list of pending merges.

As, I said the issue has been fixed in TFS 2012 Update 2, so your solution is to upgrade to TFS 2012 Update 2.

Thursday, 13 June 2013

Failed to generate a user instance of SQL Server due to a failure in starting the process for the user instance. The connection will be closed

I haven't had much chance to use SQL Server Express Edition of late. So, when I hit an issue an on an environment using SQL Server Express Edition last night, I thought to use the opportunity to read around. I must say that Microsoft progressed appreciably the whole portable database story and it has come a long way since the days of MSDE.

First let me explain the  issue I was looking at, in case it might help some troubled soul. So, on an environment using SQL Server Express 2008, I started getting the following error

"Failed to generate a user instance of SQL Server due to a failure in starting the process for the user instance. The connection will be closed."

Not knowing what caused it, I tried to Google the error and got many posts suggested to delete the local database file copied to the folder "C:\Users\MyUserName\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS"

Did that and restarted but the error persisted. Then I stumbled upon the following post http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/60889070-5c3c-4823-ae9f-1ed6e32b2ce8/ indicating that the user instance feature of SQL Server 2008 has been deprecated. That was a good pointer. Changed my connection string from 

"Data Source=.\SQLExpress;Initial Catalog=mydbfilepath;Integrated Security=SSPI;MultipleActiveResultSets=true


"Data Source=.\SQLExpress;Initial Catalog=mydbname;Integrated Security=SSPI;MultipleActiveResultSets=true"

And that worked.

Coming back to the original topic, there are three flavors of portable databases available for SQL Server for small scale usage and for developers.

SOL Server Express
SQL Server express is the freely available and downloadable version of SQL Server that can be used for small scale applications. The change here is the User Instances have been deprecated from SQL Server Express 2008 onward.

SQL Server Compact
SQL Server compact is a very lightweight version of SQL Server that can connect to a database file. It is In-process DLL, which means it is an ideal candidate to meet all your IMDB (In Memory  Database) needs.

SQL Server Local DB
SQL Server local DB is designed specifically for developers and differs from SQL Server in that it min version of SQL Express with less pre-requisites.

This post compares the three flavors rather well.

Thursday, 18 April 2013

CI build, deployment Items and Copy to output directory

As I started to write this blog post, I must admit, I struggled with find an appropriate heading for it. We can put this blog post in the "How I got burnt category" category.

So, we are running our CI builds using TFS 2012 and with very little customisation to the out-of-the-box build template and it all works a treat. However, occasionally our builds are failing with the following error

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3686): Unable to copy file "C:\CI\77\src\...." to "C:\CI\77\bin\....". Access to the path 'C:\CI\77\bin\....' is denied.

Looking closely, there were two traits of the files for which we were getting this error.

  1. The files had the "Copy to Output directory" property set to "Copy Always".

  1. The files were present as an "Deployment Item" in a Test class.

We had a few XAML files, which had to be loaded dynamically in our tests, so the DeploymentItem was needed.

The error happened in the  "_CopyOutOfDateSourceItemsToOutputDirectoryAlways" target in the Microsoft.Common.targets file, which is executed when MSBUILD is attempting to copy all files with the setting "Always Copy to output directory" to the output directory.

The error seems to have happened because the CI Build tried to copy a file after it has been deployed as a deployment item. We did have BuildInParallel attribute set to true. In our case, we realised that the "Copy to output directory" was not needed, so we changed the setting to "Do not copy". In other scenarios where both the conditions are needed, the solution would be to set the BuildInParallel parameter to false. 

Tuesday, 16 April 2013

Clearing Windows Server AppFabric databases

If you have been using Windows Service AppFabric, you would be aware of the two AppFabric databases. The AppFabric Monitoring database and AppFabric Persistence database. The Monitoring database stores events information while the persistence database store information about instance data and metadata.

It is often are requirement to clean up the database, especially if you deploying to a clean environment. The following MSBuild file will help do that.

    <UsingTask TaskFactory="PowershellTaskFactory" TaskName="ResetAppFabricDatabases" AssemblyFile="$(PowerShellAssemblyFile)">
            <AppFabAdmins Required="true" ParameterType="System.String"/>
            <AppFabReaders Required="true" ParameterType="System.String"/>
            <AppFabUsers Required="true" ParameterType="System.String"/>
            <MonitoringDbName Required="true" ParameterType="System.String" />
            <MonitoringDbServer Required="true" ParameterType="System.String" />
            <PersistenceDbName Required="true" ParameterType="System.String" />
            <PersistenceDbServer Required="true" ParameterType="System.String" />
            <ConfirmPreference Required="true" ParameterType="System.String" />
                            $executionPolicy = Get-ExecutionPolicy
                            Set-ExecutionPolicy Unrestricted                        
                Import-Module ApplicationServer
                $log.LogMessage([Microsoft.Build.Framework.MessageImportance]"Normal", "Removing persistance database {0} on sql instance {1}.", $PersistenceDbName, $PersistenceDbServer)
                Remove-ASPersistenceSqlDatabase -Force -Server $PersistenceDbServer -Database $PersistenceDbName            
                $log.LogMessage([Microsoft.Build.Framework.MessageImportance]"Normal", "Creating persistance database.")
                Initialize-ASPersistenceSqlDatabase -Admins $AppFabAdmins -Readers $AppFabReaders -Users $AppFabUsers -Database $PersistenceDbName -Server $PersistenceDbServer
                $log.LogMessage([Microsoft.Build.Framework.MessageImportance]"Normal", "Clearing Monitoring Database {0} on sql instance {1}.", $MonitoringDbName, $MonitoringDbServer)
                Clear-ASMonitoringSqlDatabase -Database $MonitoringDbName -Server $MonitoringDbServer                        
                            Set-ExecutionPolicy $executionPolicy                        

Just call the Target  "ResetAppFabricDatabases" from your project file as shown below.

Please note that you would need to have MSBuildExtensions pack installed on your machine to run this script.

    <Target Name="ClearDownAppFabric">
        <ResetAppFabricDatabases AppFabAdmins="$(Domain)\$(AppFabricAdministratorsGroup)"

You can download the sample from here

Thursday, 11 April 2013

Work Items loosing formatting when edited in Microsoft Excel

Recently, we upgraded to Team Foundation Server 2012 for our project. The upgrade was generally a smooth affair and apart from a few niggles went out trouble free. Here is one of the niggles we faced, so I thought to blog about it here.

A sizeable number of people in our team use Microsoft Excel to edit work item especially where there is a lot of text to write such as Test Cases. It only takes a couple of clicks to open the work item in Microsoft Excel and user can use the rich editing functionality provided by Office.

However, after we moved to TFS 2012, editing work item description in Excel would show the following warning and the description would lose all its formatting.

As, it turns out the change in behaviour is caused because the upgrade process had changed the type of our Description field from PlainText to HTML. 

However, Team Foundation Server doesn't allow editing the actual HTML of the fields. This means that the text typed in Excel would be published without any of its tags and that is the reason that it lost its formatting. Here is the reason why Microsoft wouldn't allow HTML editing.

For us, it was important to keep the ability of editing work item in Excel, so the solution was to change the type of System.Description field to PlainText. This can be done by using the Witadmin utility. Following is the command that I executed. 

witadmin changefield /collection:<ProjectCollectionUrl> /n:System.Description /type:PlainText
Please note that the change will happen at Project Collection level and you will need to have appropriate permissions on all team projects within the collection. 

Some Updates

As I resumed blogging this time around, I swore to myself that I would post more frequently this time. It wasn't to be. My last post was done about month and half ago. So, now that I am done with my work for the day and I have got some good bedtime reading with me, I thought its' about time to write a quick post.

Life has not been dull in the last month or no… far from it. In the midst of some very busy office work and a short holiday trip, there has been some good learning and quite a few things to share. I will post about them soon. But first, I have got two exciting news to share

The first one is that I am a father for the first time. Our little boy was born early last month. He is slowly coming to terms with this world and is continuously keeping us enthralled.

The second great news is that I have been inducted into the Visual Studio ALM rangers program. Special thanks to Mike Fourie for recommending me. Here is the post from Willy-Peter Schaub introducing me to the program. I am thrilled to bits to be part of the program. The rangers program has released some great software in the past and I am looking forward to contributing positively.

Tuesday, 19 February 2013

Scaling up with Agile

One of the  things about Agile that has intrigued me for years is how does it scale up to a truly enterprise scale. It is therefore, really interesting to see how main players in in the industry like Microsoft are using and reaping the benefits of Agile for its mainline products. I found the following video  of Dean Leffingwelll explaining scaling Agile project as very insightful. The video is about an hour long but it's well worth it in my opinion.

One of the key points from the talk is that how Agile needs to be implemented top down and how the top-management needs to "have their bacon" in the Agile projects as well. Over the last few years, I have had the privilege of working in some really good Agile projects where Agile makes catering changing priorities rather easy. But, I have seen the dark side where using Agile methodologies resulted in mayhem and a series of partially completed deliverables.

Using Agile doesn't mean that the "destination" is not known. A programme / project would still need a business case (why), specification (stories in Agile) and an acceptance criteria.