TFS Work Item Templates Filtering User Selector


If you are managing multiple Team Foundation Server (TFS) project teams then you probably would prefer to filter the user/people selector based on project or roles. The standard list includes all users, which contains more users than necessary.

Visual Studio provides an option to modify the work item templates. You can access this option at Tools-Process Editor-Work Item Types-Open WIT From Server. Select the Team Foundation Server and Project Collection before clicking Connect. The available work item templates will appear. Next, select the appropriate template to apply the filter. In this example, the User Story was selected.

 On the Fields tab, select the Assigned To field.

After selecting the field, the Fields Definition will be presented.

Click the Rules tab, which provides the filtering options for the Assigned To field.

Select ALLOWEDVALUES and click Edit. You can assign a project group with the [project] placeholder and the name. In my case, assigning the TFS project team.

Once you save the work item template, visiting a User Story and selecting the Assigned To field will display the filtered user list.

You can also export the work item template and add to TFS source control. In this case, modifying the following XML will also update the filter.

 XML |  copy code |? 
<FieldDefinition name="Assigned To" refname="System.AssignedTo" type="String" syncnamechanges="true" reportable="dimension">
  <ALLOWEDVALUES expanditems="true" filteritems="excludegroups">
    <LISTITEM value="[project]\My Team" />
  <HELPTEXT>The person currently working on this story</HELPTEXT>

Hopefully, this tip can save you time applying a filter to a user/people selector.

TFS Build Process Packaging


In previous posts, we discussed various techniques to tailor your Team Foundation Server (TFS) Build Process. The TFS Versioning article introduced a library, which enables you to set the assembly versions during the build. The TFS Merge post demonstrates the steps necessary to provide a merge process within the TFS Build Process Template. In this article, we explore the Build Process Parameters of the TFS Build Process Definition.

After you successfully compile and test, the final step is packaging and/or publishing the product for deployment. If your build process definition includes multiple source solutions then collecting the assets required to deploy is tricky. In most scenarios, you will move the packages and artifacts to a share or drop location. The versioning process provides a unique identifier, so you can properly label or tag the deployment release. If you create a share folder name with the generated version then you can catalog and track the deployment releases.

The MSBuild command-line provides a series of parameters instructing the build to perform one or more defined operations. The parameters will override any solution or project specific values, which is helpful to ensure the results are consistent for packaging and publishing.

The MSBuild Parameters is an Advanced section option, which provides the override instructions to the build process. The web projects are packaged to include the required assets to deploy, which appear as a “_PublishedWebsites” folder. A SharePoint Solution Package (.wsp) and SQL Server DAC Package (.dacpac) are other examples of deployment packages.

The following MSBuild parameters will ensure the above packages are created during the build process.

TFS Build Definition MSBuild Arguments

The OutputPath parameter is optional, but will move results to the bin folder. This includes the web, SharePoint and SQL Server deployment packages discussed previously. The WarningLevel parameter is set to zero, so all warning messages are suppressed.

I hope this information is helpful, so you can customize your build process and capture the deployment packages without writing significant custom logic.

Automate Merge With TFS Build


In the previous TFS Build Process Template and Versioning post, we discussed customizing your Team Foundation Server (TFS) build workflow to dynamically inject the build number into the assembly version. This post will present a process to automate the merge process within a TFS build template. This feature would benefit organizations maintaining a development branch, which requires merging into the main or trunk after a successful release.

The following custom workflow sequence can be included as the final activity of the development build, which will be conditionally executed based on successful build and test results. If you are not performing manual merge processes then you should not encounter conflicts. I would recommend creating a copy of your current build template and add a name prefix as a version number. For example: MyBuildTemplate.2.xaml. Once you have tested the new version, you can replace the current MyBuildTemplate.1.xaml with MyBuildTemplate.2.xaml.

The following is the high-level Merge sequence illustrated in the workflow.

Merge Sequence

The first step is add the arguments, which will be the input to drive the merge process. The parameters should be exposed in the build definition and Queue Build prompt.

Merge Arguments

The SourceMergeBranchPath and TargetMergeBranchPath contain the paths to the TFS location, where the source changes are the “to be” merged into the target. The MergeOptions will allow you to select the appropriate merge option to apply to the process, which will be discussed later in this article.

Next, we will add the logic into the Merge sequence starting with a conditional statement verifying the 2 argument values are valid. The MergeOptions argument is a default, so no validation is required.

Merge Validate Required Arguments

If the required arguments are validated then we begin the merge using another sequence to wrap the logic. The Else path will add a message to the build and exit the merge sequence.

The expanded Merge Begin sequence appears in the image below.

Merge Begin Sequence

The key step is the Run Merge, which is assigns the GetStatus value. The merge process is executed as a method of the Workspace object. The following is the method call to perform the merge.

Workspace.Merge(SourceMergeBranchPath, TargetMergeBranchPath, Nothing, Nothing, LockLevel.None, RecursionType.Full, MergeOptions)

The first 2 parameters are the source and target merge branch paths, which are 2 arguments we discussed previously. The final parameter is the MergeOptions argument, which we can set in the build definition or queue build prompt. The result will be assigned to GetStatus, which will analyze in the next steps.

Merge Conflicts

In the above condition, we check if conflicts or errors were encountered by checking the GetStatus object. If the counts are zero then we can continue to follow the success merge path. If a failure or conflict is encountered then we report the issues and abort the merge process. This path will require additional review and decision.

The GetPendingChanges is also an assignment, which represents the pending changes as a result of the merge. The Workspace.GetPendingChanges will return a collection of the pending changes and the next condition will process any changes.

Merge Process Pending Changes

The Process Pending Changes sequence will include a ForEach to process each pending change. In this process, we are simply recording the change for the build log.

Merge Report Pending Change

When you select a Visual Studio merge, you must perform a check-in after you resolve all conflicts within your workspace. So…the next step is to checkin or commit the changes. The Checkin Pending Changes sequence is responsible for this task.

Merge Checkin Pending Changes

The Run Checkin is also an assignment, where again we call a Workspace method to perform the checkin of the workspace pending changes. The following is the Expression Editor with the CheckinResult assignment.

Merge Checkin Pending Changes

The PendingChanges was a previous assignment and the second parameter are the comments applied to the checkin process. In this example, we assign a standard checkin comment for the changeset. 

If we switch to the Else path of the Pending Changes condition then we would report no pending changes to checkin. The merge is still successful, but no changes were processed.

So…we also need to complete the Else path of the Merge Begin sequence, where we check for failures and conflicts. We just completed the successful merge path, where no failures or conflicts were reported. The following is the Display Merge Results sequence, which reports the failures and/or conflicts to be reviewed.

Merge Report Conflict

The conflict and failures reporting process is essentially the same, where the ForEach will process each item of the collection and a WriteDeploymentInformation can log an entry. The final merge status or result is a failure, so you can also set the build status value accordingly.

We completed the review of the Merge process, which can easily incorporate into your TFS build template and perform an automated merge. The final topic is the Merge Options parameter, which we introduced earlier as an argument. This is also a parameter of the Workspace Merge method, which instructs the process to follow the appropriate conflict resolution defined by the build definition or manual build. The following are the options and a brief explanation, so you can assign the appropriate merge option for your process.

  • None – no special options
  • AlwaysAcceptMine – discard any changes as resolve conflicts using AlwaysAcceptYours resolution
  • ForceMerge – same as tf.exe force option
  • Baseless – source and target items have no branch relationship
  • NoMerge – same as tf.exe preview option

You can also update the Process Parameter Metadata, so it includes helpful information for the user. This appears below for the 3 merge arguments we setup earlier.

Merge Process Parameter Metadata

I hope this article provides an option for an automated TFS build process merge process. This implementation requires no external or third-party assemblies, so it should be easy to add to your current build templates. Since this is an independent build process, I would recommend creating a merge workflow template and calling the merge as a child of your main build template. This should be based on the success of your build and test, so the automated merge is executed during a successful build result.

TFS Build Process Template and Versioning


I am currently enjoying the wealth of new Visual Studio 2012 features. It was a few days before I really appreciated the new user experience, since productivity and access to common options are much improved. This is not the focus of this article, but I thought it was worth mentioning. This post is about sharing and saving time.

The TFS 2012 default XAML build template does not provide support for versioning, which is a feature that provides injecting assembly version and build information. This information is critical to validate a deployment by checking the assemblies and collecting the unique version number. This value is a combination of the major version, minor version, build number and revision. You can view the version information by selecting the assembly file properties under the details tab.

Assembly File Properties

The project AssemblyInfo file maintains the values for the version information. The AssemblyFileVersionAttribute contains a build number, so this information should be changed during every build. In this scenario, the AssemblyFileVersionAttribute should be associated with a specific TFS build. This can be accomplished by customizing the default build template to include a process to assign a unique version number linked to the build.

The first step is create a copy of the default XAML build template and add to source control. You can rename this file, since it will be a custom XAML template. Next, download the Community TFS Build Extensions from CodePlex, which contains a collection of code activities to extend the current core functionality. This includes the TfsVersion activity, which is a versioning task supporting the assignment and assembly file injection of the information. You must add the Community TFS Build Extension assemblies to source control and reference the custom assemblies with the TFS Build Controller.

The following are the modifications required, so change the new XAML build template created earlier. It is easier to create a new TFSBuild project, add the assembly references and link (i.e. not add to the project) to the XAML build template. If you do not setup a project then editing the XAML is difficult without the activities appearing in the Toolbox. 

Add the Major, Minor and TFSVersionNumber arguments to the build template.

Build Template Arguments

Click the Metadata arguments selection and add the Major, Minor and TFSVersion parameters below, so the build definition will provide help and categorized information.

Build Template Metadata Major

Build Template Metadata Minor

Build Template Metadata TFSVersionNumber

The TFSVersionNumber is only available when queuing a build, so it will not appear in the build definition. This provides the option to override the generated version number when manually triggering a build. This will be handled with a conditional, so if the value is set then skip generating a version number. The Major and Minor parameters are assigned with the build definition or queuing a manual build. The three parameters will be grouped under the Versioning category, so they will be easier to manage.

Next, add the build template items to assign the version number.

Build Template SetVersionNumber

The new activities must appear within the current Update Build Number For Triggered Builds, so the build number/name is assigned the same value as the assembly information. If the TFSVersionNumber is not set then SetVersionNumber conditional executes GetTFSVersion to assign the value for the build. The GetTFSVersion properties appear below, which generates the version number based on the Major and Minor values. The unique build number is assigned as the 3rd element of the version number, which are all separated by a delimiter.

Build Template GetTfsVersion Properties

The Action property is set to GetVersion, so the generated version number is assigned to the TFSVersionNumber. It is assigned as the build number and file version in subsequent tasks.

Build Template GetTfsVersion Properties Version

The current Update Build Number is changed to assign the TFSVersionNumber, so the build number is the same value as the version number. I recommend appending the build definition name, so the following is an example.

  • MyBuildDefinition_2.1.167.01

The final step is the file versioning, where the version number is injected into the AssemblyInfo files before compiling. The following is the build template with the new items.

ild Template ApplyVersionNumber

The Apply FileVersionNumber appears after the current Get Workspace, which contains a condition to verify the TFSVersionNumber is assigned. The TFSFileVersioning sequence includes FileMatchingAssemblyInfo and SetTfsVersion. The FileMatchingAssemblyInfo properties appear below, which basically generates a list of AssemblyInfo files from the current workspace.

Build Template SetVersionNumber FindingMatchingFiles

The SetTfsFileVersioning properties appear in the next image, which accept the AssemblyFiles collection and TFSVersionNumber.

Build Template SetVersionNumber Properties

The TfsVersion activity is again handling the work, but in this case injecting the previously generated version number into the AssemblyInfo files.

After almost committing to building custom activities to perform the same tasks, I stumbled onto the TFS Community Build Extensions and the very helpful TfsVersion activity. After a few more hours of testing the various options, I arrived at the above process. In my case, synchronizing the build number and AssemblyFileVersion was the objective. If you seek a slightly different process then I would look at the TFS Community Build Extensions and the TfsVersion activity options.

In the end, I hope this saves you a little time and research. If you find something helpful then please comment and share.

Go to Top