Get started with some basic TFBuild scripts

You want to run some of your business logic during your TFBuild process. Maybe before, or maybe after Team Foundation Build (TFBuild) compiles or tests your code. For example, before you compile, you want to set the version of your assembly files. Or after you compile, you want to control the build outputs that get dropped to your staging location.

Until recently, you would have to customize your build process. Plenty has been written about how to develop a custom build process. I recently released a topic that I hope makes getting started on this kind of effort a bit easier: Create a custom build process. Regardless, developing and using custom build process activities of any complexity can be tricky and requires a learning curve.

What if you just want to run a simple batch (.bat) file? Or maybe you need a bit more power and you want to run a PowerShell script, perhaps to leverage even a bit of .Net code. Well, I’m here to share some good news: with Visual Studio and Team Foundation Server 2013 you can do it! In fact, to help you kick off your adventure in TFBuild scripting, following are a few examples you can literally copy, paste, and check in to your team project and use today.

As you can see, the following build definition is based on the default template; no customizations up my sleeve:

Default build process that runs basic scripts

Before you begin using these scripts, a few bits about how they work:

  • ApplyVersionToAssemblies
    • The Build number format is set to provide the script with the version data it needs in form, as shown above.
    • The script applies the version data to your AssemblyInfo files so that it is stamped on the binaries when they are compiled.
  • GatherItemsForDrop
    • Output location is set to AsConfigured so that the script controls what output files are dropped later in the build process.
    • After the code is compiled, the script copies binaries from the source folder to the binaries folder so that these files can later be dropped to your staging location.

To use these scripts, simply copy the code below into .ps1 files, check them into your codebase, and then reference them from your build process as shown above. Also make sure to include the folder that contains your script on the build definition Workspace tab.

Run a script before building: version your assemblies

While there are many tasks you might want to perform before MSBuild compiles your code, one of the most common of these might be to apply a version to your assemblies. Jim Lamb wrote a canonical blog post on build process customization: Create a Custom WF Activity to Sync Version and Build Numbers. I patterned the following script using his approach to assembly versioning.

You can get this script here:

Run a script after building: prepare your binaries to be staged

When you set Output location to AsConfigured, TFBuild yields control of which binaries are dropped to you. The binaries are compiled and left in the source directory, organized essentially the same way as if you used Visual Studio to compile them locally on your dev machine. The following script gathers some of the typical binary types from the typical locations and copies them to the folder from which TFBuild copies and drops to your staging location.

You can get this script here:

A few final bits

You’ll notice that these scripts leverage some environment variables to get the key bits of data they need to perform their functions. I’ve cataloged these and all the other environment variables that are available to your scripts: Run your scripts in a default build process. (Note: there is a known bug with the TF_BUILD_TESTRESULTSDIRECTORY not being correctly handled by TFS 2013 Preview. This bug will be fixed in the next release.)

To debug the script while logged on to your dev machine or on the build server, you can manually set the TF_BUILD environment variables in your PowerShell console session. In fact, you’ll notice the scripts automatically prompts you to do so. Use the -verbose parameter if you want to get details about what the script is doing and view them from the diagnostic log. Specify -disable if you want to disable any changes the script might make while leaving it referenced by your build process.

I invite you to post your comments here. For questions, I encourage you to post them on our forums: