For the fast few years I have been using git as source control. But I’m sure like most people who work with Microsoft technologies, I’ve had to use TFVC in hte past and (if you’re a little bit unfortunate) the present. One of the drawbacks of TFS is that branches become long lasting objects and all too often someone somewhere has made the well-meaning but misjudged attempt at using lots of branches as like boundaries to prevent bugs accessing code. In the long run all this really does is slow down deployments and cause merge hell. The guidelines from Microsoft contradict many of the behaviours that many dev teams adopt.

However one of the strategys, Feature Isolation, This feature branch is deliberately short-lived, meaning that many branches may be created and deleted in a short space of time, and depending on the team you may have a few existing at the same time. And whilst you merge to main perhaps as little as only once, you can and should check-in and run a build and deploy as regularly as you would for any other scenario.

But with more branches there are the more build definitions there could be, all identical except for the branch they are pointed at. Fortunately it is possible to set part of the branch using a build variable. So where you have a tfvc server path of “$/server/code/feature1” “and $/server/code/feature2” you could set the branch to a build variable like $(tfs.branch), and at build time set the branch to the name of your feature branch**. So in the image below, the branch name (1) is set by filling in a variable value called tfs.branch (2) at build time (3).

Setting Branch at Build

However, this process is not something that is immediately obvious to all team members. So it’s necessary to add a check to make sure that the variable cannot be empty when a build is run, elsewise I can imagine the branch not being set and the builds failing. Because there would be no branch to download from would not cause an error, but trying to compile a proj file that was never downloaded would fail, but it would not be clear why it wasn’t downloaded if you don’t know that you need to set the branch! A simple step in the build to check it is not null or empty could be added, but to make this a tiny bit more interesting I’ve added a PowerShell script that takes the tfs.branch parameter as a mandatory value and prints this out to the console. This is the script:

param (
   # Folder path to the directory that contains the *proj file
   [parameter(Mandatory = $true)] $tfsBranch

$convertToAscii = Resolve-Path(Join-Path $PSScriptRoot ConvertToAsciiArt\ConvertToAsciiArt.ps1)

Write-Host "The branch being downloaded is:"

. $convertToAscii -Text $tfsBranch -Online -FontName big

Now what this is running is an amazing script called ConvertToAsciiArt. This does what it says: it takes some text and prints out the characters in ASCII.

Print Out Branch

If there is no value set at build time the step fails. Maybe in retrospect I should change it to a non-mandatory parameter and if it is null or empty then throw an error saying that $(tfs.branch) needs to be set to a branch, but alternately the name of the variable missing should be self-explanatory.

** Currently I have this as a manual process. I’m sure through the API you could set up some sort of polling against a set of branches and then when a check in happens invoke a specific build with a build variable set as the name of the pertinent branch.