Building Azure and SharePoint packages during Team Build

Przemysław Orlik

CustomizableUX_WebSome time ago one of my colleagues needed to create one build definition for building a solution he was working on. The solution consisted of 2 Visual Studio solutions, one for the backend and one for the frontend. For the backend he was using Azure Could Service with Web Role and for the a frontend there was this small SharePoint app which would be installed on SharePoint Online.

I’m the person who handles Team Foundation Server infrastructure at our company so I said: no problem, we have this new and shiny Team Foundation Server 2013 Update 4 so you will have it in 5 minutes. Obviously I was wrong…

After creating the desired build definition I took it for a spin. Build succeed, what is good, but when I looked into the drop folder, SharePoint package and Azure package were not there. I forgot to include packaging parameters in the MSBuild arguments part of the build definition so I added necessary parameters for the SharePoint app

/p:IsPackaging=true /p:AppSpecificPublishOutputs=true

But still no luck and no packages in the drop folder.

I looked for the possible solution and I found the necessary parameters for packaging the Azure package – maybe this will work. I’ve removed previous MSBuild arguments from the build definition and set them to

/p:TargetProfile=Cloud /t:publish

Still no luck no – this time I was looking for Azure package in the drop but it wasn’t there.

I deliberately did not define the /p:PublishDir parameter because I wanted the packages to land in the drop folder of a particular build and not in some other directory.

I went to the build server and discovered that the publishing works perfect – or to be more precise almost perfect. Packages were created during team build ,but not in the binaries folder but in the sources folder! They should be in

C:\b02\7\Build Test\Contoso Build\bin\app.publish\ContosoSharePointApp\

But instead they were in

C:\b02\7\Build Test\Contoso Build\src\ContosoSharePointApp\ContosoSharePointApp\bin\Release\app.publish\ContosoSharePointApp\

That was obviously wrong. When the build copied binaries to the drop it took files from the bin folder and not the src!

Long story, short I got to the point where I decided to do it in a more complex way. Below is the solution explaining how you can configure it to get one build that builds one solution with content for Azure and another solution with content for SharePoint Online, and you expect to get packages for deployment as an output.

First if all, each of the solutions mentioned above requires different MSBuild arguments. I used MSBuild response files to set different arguments for different solutions.

You need to create a file called msbuild.rsp, put the parameters in that file and make sure it is located next to the sln file in the source control.

Azure Solution msbuild.rsp location

Make sure the file has proper parameters inside:  /p:TargetProfile=Cloud /t:publish

SharePoint solution msbuild.rsp location


Make sure the file has proper parameters inside: /p:IsPackaging=true /p:AppSpecificPublishOutputs=true

At this point parameters are set for your solutions. Now you have to make sure that build will publish packages in the drop folder.

You need to use /p:PublishDir parameter so the packages get published into specified location. The trick is to use the binaries folder as the publish directory. I used the following solution. In the MSBuild arguments I specified /p:PublishDir=”{BinariesDirectory}\\” and I modified the build process template to replace the {BinariesDirectory} with the real value – path to the binaries folder. With this approach you can also use {BinariesDirectory} for other purposes in your MSBuild arguments.

Set build definition MSBuild arguments


Edit process template


  1. Download your process template. In my case this is default template (TfvcTemplate.12.xaml)
  2. Open the downloaded template file in Visual Studio and find the Run MSBuild activity (Overall build process -> Run on agent -> Try)
  3. Create a string variable called BinariesDirectory in the process template.build6
  4. Before the Run MSBuild activity place activity of type GetEnvironmentVariable<T>build6

5. Set the properties of the GetEnvironmentVariable For the name use the Microsoft.TeamFoundation.Build.Activities.Extensions.WellKnownEnvironmentVariables.BinariesDirectory and assign result to the newly created variable BinariesDirectorybuild7

6. Edit properties of the Run MSBuild


Open CommandLineArguments property and change it


String.Format(“/p:SkipInvalidConfigurations=true {0}”, AdvancedBuildSettings.GetValue(Of String)(“MSBuildArguments”, String.Empty))


String.Format(“/p:SkipInvalidConfigurations=true {0}”, AdvancedBuildSettings.GetValue(Of String)(“MSBuildArguments”, String.Empty).Replace(“{BinariesDirectory}”, BinariesDirectory))

7. Save your customized template to the source control. You have to update your build definition to use the customized process template. First you need to add it to your source control. I used Source Control Explorer for that. Create new folder called Process templates and add your customized template. Make sure you check it in before continuing.



In the process part of your build definition click New… in the build process template section


Then click Browse… and find your template.


At this point you should see your own custom template selected


Save your modifications in the build definition and run it!

Once the build is completed your packages should be in the drop folder.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s