Manipulating your TFVC repository from Build 2015


Though generally considered a bad practice I crafted two build tasks to manipulate your TFVC repository from the build. You can now edit, delete and add files and check those changes in when you're ready.

Before I explain how they work and how you can use them, I need to get the following out of the way:

I do not think it's a good idea to change your sources as part of a build.
Unless that's the only thing your build definition does.
In these cases it should not build your sources and produce your shipping artifacts.

The reason why I'm reluctant, is that changing your sources during the build has impact on other features of the Visual Studio Team Services platform. 
  1. As your code is being built, certain artifacts are generated, such as your debug symbols, test results, code coverage etc. And these artifacts are associated with the Changeset number of the build. This may break or cause problems with Remote debugging, Source Server support, Intellitrace and Test Impact Analysis among other features. Other tools that may be impacted are obfuscators.
  2. Since your scripts change files, features such as Incremental builds won't work. They'll always have to rebuild the projects, since there are always modified files. This is especially so when you use tasks to patch the AssemblyVersion attribute. This will slow down your builds slow down the feedback cycle as a result.
So, now I hope you understand this is a bad idea and you may wonder why I chose to build these tasks anyway.

The primary reason I built these, is to help clients migrate from customized XAML builds to the new build system with minimal impact. I'd rather have them fix their mistakes in the new system, than delay their move by fixing it in the XAML workflows.

The secondary reason I built these, is to provide ways to schedule changes to sources automatically. You may have a manual build trigger which updates all the version numbers and checks in the changed files, which in turn triggers a CI build to build the code. By using this two-stage approach, your build and symbols will be associated with the correct changeset and you won't have the issues described before.

I'm not terribly happy about the quality of the code, yet, but that will improve now that they do the thing they're required to do. I admit I've learned way too much about Powershell/.NET interop in the past days...

You may ask why I didn't simply wrap tf.exe, but I assure you, I've tried. It fails to perform the check-in as it doesn't pick-up the security token authentication used by the new Build system. You'll be greeted by a cryptic security error when you try to check in the files:

#[error]TF30063: You are not authorized to access
#[error]Process completed with exit code 100 and had 1 error(s) written to the error stream.

Introducing the TFCV Build tasks

So with those warnings and a bit of guidance I present to you the VSTS-TFVC-Tasks project on Github. Which consists of two tasks for the new 2015 build system:

TFVC Check-in changes

The first task checks in any changes and deletes you've made to your $(Build.SourcesDirectory), optionally scoped to a specific path. It's able to by-pass your checkin policies and can optionally suppress a CI build by adding a specific comment.

Since Build 2015 uses Local workspaces any edit or delete is automatically detected.

  • I understand - if your build system dived into an endless loop, uses up all your build minutes or destroys your source tree by accident. You've signaled you understand this risk, the task won't work without this consent.
  • Files to check in - specify one or more paths, separated by ; or newline. While wildcards (?, *) are supported, they're not the same as the minimatch patterns used by other build tasks. 
  • Recursion - controls whether you'll be checking in just the current folder/file (None), one level below the selected path (One Level) or all levels below the selected path (Full).
  • Check-in comment - The comment which will show up in the source control history for this changeset.
  • Notes - specify one or more checkin notes using the following format Name=Value separated by ; or newline.
Policy Override
  • Bypass CI on check in - adds a special string to the check-in comment to ensure that no other build is triggered.
  • Override policies - to override any check-in policies or changeset-notes that may be required by your administrator.
  • Override reason - when enabling Override Policies, you're required to specify a reason. This reason is stored with the changeset.

TFVC Add new files

Unlike edits and deletes, additions aren't automatically checked in, they need to be signaled before they'll be picked up by the Check-in task. Adding them is simple, just specify the paths you want included and they'll be added to the list.

  • Files to add - specify one or more paths, separated by ; or newline. While wildcards (?, *) are supported, they're not the same as the minimatch patterns used by other build tasks. 
  • Recursive - controls whether you'll be checking in just the current folder/file (unechecked), or all levels below the selected path (checked).
  • Apply Localitem Exclusions - will ignore files that are specified in your .tfignore file if your repository has one.


To install these tasks you'll need to install Node.js and the tfs-cli node package using the instructions described here. Then configure your Project Collection uri using tfx login. After that you can either run the publish.ps1 . script in the repository or issue the tfx build tasks upload command yourself for each task you're interested in.

To install these tasks to a TFS 2015 server, you'll need to configure Basic Authentication on your application tier or use this trick to let Fiddler handle the authentication for you.

Search This Blog


Most Reading