Category Archives: 17024

Building Azure Cloud Applications on TFS

If you are doing any work with Azure Cloud Applications there is a very good chance you will want your automated build process to produce the .CSPKG deployment file, you might even want it to do the deployment too.

On our TFS build system, it turns out this is not a straight forward as you might hope. The problem is that the MSbuild publish target that creates the files creates them in the $(build agent working folder)\source\myproject\bin\debug folder. Unlike the output of the build target which puts them in the $(build agent working folder)\binaries\ folder which gets copied to the build drops location. Hence though the files are created they are not accessible with the rest of the built items to the team.

I have battled to sort this for a while, trying to avoid the need to edit our customised TFS build process template. This is something we try to avoid where possible, favouring environment variables and MSbuild arguments where we can get away with it. There is no point denying that editing build process templates is a pain point on TFS.

The solution – editing the process template

Turns out a colleague had fixed the same problem a few projects ago and the functionality was already hidden in our standard TFS build process template. The problem was it was not documented; a lesson for all of us, that it is a very good idea to put customisation information in a searchable location so others find customisations that are not immediate obvious. Frankly this is one of the main purposes of this blog, somewhere I can find what I did that years, as I won’t remember the details.

Anyway the key is to make sure the publish target for the MSBbuild uses the correct location to create the files. This is done using a pair of MSBuild arguments in the advanced section of the build configuration

  • /t:MyCloudApp:Publish –  this tells MSbuild to perform the publish action for just the project MyCloudApp. You might be able to just go /t:Publish if only one project in your solution has a Publish target
  • /p:PublishDir=$(OutDir) – this is the magic. We pass in the temporary variable $(OutDir). At this point we don’t know the target binary location as it is build agent/instance specific, customisation in the TFS build process template converts this temporary value to the correct path.

In the build process template in the Initialize Variable sequence within Run on Agent add a If Activity.

image

  • Set the condition to MSBuildArguments.Contains(“$(OutDir)”)
  • Within the true branch add an Assignment activity for the MSBuildArguments variable to MSBuildArguments.Replace(“$(OutDir)”, String.Format(“{0}\{1}\\”, BinariesDirectory, “Packages”))

This will swap the $(OutDir) for the correct TFS binaries location within that build.

After that it all just works as expected. The CSPKG file etc. ends up in the drops location.

Other things that did not work (prior to TFS 2013)

I had also looked a running a PowerShell script at the end of the build process or adding an AfterPublish target within the MSBuild process (by added it to the project file manually) that did a file copy. Both these methods suffered the problem that when the MSBuild command ran it did not know the location to drop the files into. Hence the need for the customisation above.

Now I should point out that though we are running TFS 2013 this project was targeting the TFS 2012 build tools, so I had to use the solution outlined above, a process template edit. However, if we had been using the TFS 2013 process template as our base for customisation then we would have had another way to get around the problem.

TFS 2013 exposes the current build settings as environment variables. This would allow us to use a AfterPublish MSBuild Target something like

<Target Name="CustomPostPublishActions" AfterTargets="AfterPublish" Condition="'$(TF_BUILD_DROPLOCATION)' != ''">
  <Exec Command="echo Post-PUBLISH event: Copying published files to: $(TF_BUILD_DROPLOCATION)" />
  <Exec Command="xcopy &quot;$(ProjectDir)bin\$(ConfigurationName)\app.publish&quot; &quot;$(TF_BUILD_DROPLOCATION)\app.publish&quot; /y " />
</Target>

So maybe a simpler option for the future?


The moral of the story document your customisations and let your whole team know they exist

Black Marble is hosting the Yorkshire Chapter of the Global Windows Azure Bootcamp on the 27th of April

Black Marble is hosting the Yorkshire Chapter of the Global Windows Azure Bootcamp taking place in several locations globally on the April 27th, 2013. This free community organised event is one day deep dive class where you will get you up to speed on developing for Windows Azure. The class includes a trainer with deep real world experience with Windows Azure, as well as a series of labs so you can practice what you just learned.

Black Marble’s event will be run by Robert Hogg (Microsoft Integration MVP) and Steve Spencer (Windows Azure MVP). Come along and join the global Azure event of the year!

Check out the prerequisites you need to install on your PC and here to sign up

Global Azure Bootcamp Logo

A fix for my failure to login to TFSpreview.com problems

I use a number of site collections on the Azure hosted Team Foundations Service (http://tfspreview.com); I have just solved a problem that I could not login to one of them via Visual Studio (2010, Dev11 or also TEE 11, I tried then all), but I could login to my other collections. Also I could access the collection if I logged in via a browser, just not with VS; all very good for work item management, but not much help for source code check-ins.

The Problem

The problem was that when I loaded Visual Studio and tried to select the collection https://mycollection.tfspreview.com in Team Explorer the ‘Sign into Team Foundation Server’ form loaded and uploaded a few times whilst trying to redirect to an authentication provider. I then ended up with a TF31003 error. A retry or use of different credentials did not help

image

If a deleted the server from the list and tried to re-add it I got similar results, but ended up at the LiveID sign in screen, but just an error message and no means to enter details.

image

The Solution

The problem was due to cached LiveID credentials. It was suggested I clear IE9 cookies but this did not help. In the end I found the solution in the Credential Manager (Control Panel > User Accounts > Manage Users > Advanced > Manage Passwords).

I had recently installed Skydrive on my PC. This had stored a cached LiveID, the issue was it seems this cached Skydrive LiveID was being used to access TFSpreview. Unfortunately this was my personal LiveID not my work one. This personal LiveID had no rights to access the problem site collection, but I could get into the other collections because both my personal and work LiveID both had access.

So I deleted the offending cached LiveID and tried Team Explorer again and this time I was prompted for a LiveID (though the user name field did contain the wrong LiveID, I could correct it) and I could login.

image

I then loaded SkyDrive (which I had exited) it prompted me to re-enter my credential. It recreated it cached credentials and seemed happy.

Interestingly they did not seem to cause a problem this time, maybe it is an entry order issue?

I need to keep an eye on it.