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.