Mimic the XAML build's Output Location option in Build 2015

26 Jan, 2016
If you’ve been using XAML builds in the past, you’ve probably discovered that, by default, it drops all the outputs of all your projects into one folder called the Binaries Folder. Unless you do anything using a post-build script, the contents of that folder will be copied verbatim to the drop location.

In TFS 2012 a new option appeared giving you a little more control over the output location; giving you 3 options:

  1. Single Folder (like it worked in 2010)
  2. Per Project (Creates a folder per solution)
  3. As Configured (don’t redirect output, so the default would put the binaries under your project folders, as it would on your local machine by default).
If there’s one feature of XAML builds which confuses the hell out of people, it’s the Output Redirection. At first people don’t expect this to happen (they expect As Configured to be the default) and then the naming of “Per Project” confuses people even more, as it turns out that it ends up creating a subfolder for each Solution or msbuild .proj file (based on the solution name).
Build 2015 takes away this issue, by having As Configured to be the default and by offering a simple Copy and Publish Artifacts task which collects the project output and copies it to the staging location. One of the nice advantages of this setup, is that it also makes it easier to do incremental builds, speeding up your CI builds.
But, if you’re coming from a XAML build and you already have a lot of existing post-build steps that assume all your files to be in a specific folder or set of folders, it may be easier to replicate that behavior than to rewrite all these scripts.
Let us go through the three options in XAML build and let’s see how you’d handle these in Build 2015.

As Configured

This is the default behavior in Build 2015. It does whatever your project files have configured. If you are sing the default project templates of Visual Studio, that means that files are dropped in the “ProjectBinConfiguration” folder.
You’d use a standard Visual Studio Build or MsBuild task followed by a Copy and Publish Artifacts task to recursively gather the output and copy them to the Staging Location and from there to the Drop Location.
The default configuration of the Copy and Publish Build Artifacts task are to scan the $(Build.SourcesDirectory) recursively and grab the contents of every “bin” folder.

When you use As Configured in XAML builds, nothing gets copied to your drop folder, unless you actually do that. The Copy and Publish Artifacts task will do this for you. Or you can run your own powershell, batch or other script to copy your files to the $(Build.ArtifactStagingDirectory). Either pass the target location using a argument or grab it from inside your powershell script using the environment variable $env:Build_ArtifactStagingDirectory:
Then call the Publish Build Artifacts task to publish them (note don’t want to use the Copy and Publish task here, since your script has already copied the files).

Single Folder

When specifying Single Folder in XAML builds, all the binaries for all your projects will end up in the root of the drop location. This was the default in Team Foundation Server 2010 and caused a lot of confusion when people started adopting Team Build back in the days.

There are two ways to mimic this behavior. One is to build your solution with no additional options and then use the default Copy and Publish task. I assume that you may be building multiple configurations here:

If you want to grab all the folders under bin, you could simplify this further to: **bin.

This solution yields the same result, but may still cause issues with your current scripts, which may assume that msbuild redirects all outputs to a single folder. It’s not hard to create a situation that’s even closer to the old XAML build’s functionality.
The first thing you need to do is instruct the Visual Studio Build task to redirect the build output to the $(Build.BinariesDirectory).

Then simply copy everything from under $(Build.BinariesDirectory) to the staging location and publish it:

The advantage of using the intermediate Binaries Directory, is that you can do incremental builds, if you were to build directly to the $(Build.ArtifactStagingDirectory) the output will be thrown away after each build, increasing your build time when you’re not using Clean Repository and Clean Build.

Per Project

The third option in the XAML build allows you to create a subfolder for each… and here it gets confusing… Selected solution. It’s called “Project”, but I think this dates back from the 2008 era when you’d build an MsBuild Proj file. 
There is no easy way to do this in Build 2015. You could use Build Multiplexing or add multiple Visual Studio Build tasks followed by multiple Copy and Publish Build Artifacts tasks. Basically taking the technique from the SingleFolder option and adding in the name of the solution hardcoded in each task or through a custom variable.
Jesse is a passionate trainer and coach, helping teams improve their productivity and quality all the while trying to keep work fun. He is a Professional Scrum Trainer (PST) through for the Professional Scrum Foundations (PSF), Professional Scrum Master (PSM) and Developer (PSD .NET) programs. With a strong background in the .NET platform and C#, Jesse is able to translate the needs of development teams when it comes to tools to manage work, build the code and keep quality up. He has contributed to a number of open source products that extend – as well as supported commercial tools like NDepend in their integration into – Team Foundation Server. Jesse regularly blogs and contributes to numerous communities on StackExchange and MSDN networks, he has received the Microsoft Community Contributor Award three years in a row and has been recently been awarded the Microsoft Most Valuable Professional award. He’s spoken at conferences and user groups, including the Microsoft TechDays and the Scrum Day Europe. Trainer certifications: Professional Scrum Foundations Professional Scrum Master Professional Scrum Developer (.NET) Scaled Professional Scrum (SPS) Scaled Agile Program Consultant In past years Jesse has delivered ALM, Test Automation and Scrum training all over the world, most recently in Sydney, Milan and Bangalore. He has redelivered materials from industry leading partners as well as developed his own. In addition to the previously mentioned subjects Jesse has taught courses on Visual Studio, Object Oriented Analysis and Design, Design Patterns for C# developers, Unified Modelling languages and Regular Expressions. Jesse is married with Charlotte, recently became father of his first daughter and lives in a house that’s more than a century old in the beautiful city of Utrecht. He loves espresso and dark chocolate, travels a lot and takes photos everywhere he goes.

Explore related posts