Building Windows Azure Projects with Team Foundation Service
June 5, 2012 1 Comment
In the fall of 2011, Microsoft announced a preview of the Team Foundation Service, a cloud-based version of Team Foundation Server (TFS) powered by the Windows Azure Platform. This next generation of TFS doesn’t require any server component, as end-users can connect to the service over the internet from Visual Studio, and via the web-based administration console.
The preview initially enabled features software projects such as Work Item Tracking and Source Control. A subsequent release of the preview enabled the Build feature. The service now provides a pool of virtual machines running in Windows Azure that are standing by ready to compile, test, and package your applications. Having used the initial service for a couple of projects already, I was eager for the Build service to become available. To me, this rounded out the offering, and allowed me to run a TFS project with truly no on-premise computing need.
One of the first exercises I wanted to try out was to enable the building of Windows Azure projects from these build machines. In working with Windows Azure projects in Visual Studio over the past few years, I have some experience with configuring MSBuild and TFS Build to produce the desired cloud package and configuration files on a Build server. I now wanted to be able to do see the same results in the cloud.
The following describes the steps to create a Windows Azure package and configuration file from a Build using the Team Foundation Service Preview. This assumes that you have a TFS Service project and have checked-in the necessary projects into source control.
Step 1: Creating the Build Definition
The first step to building your Windows Azure projects is to create a new Build Definition:
- In Team Explorer, right-click on Builds and select “New Build Definition…”
- In the wizard, proceed through the General, Trigger, and Workspace tabs as usual in creating a new build.
- On the Build Defaults tab, select the “Hosted Build Controller (offline)” option for the Build controller. For the drop location, specify a “Drops” folder in source control for the service to place the build output. You do not need to explicitly create this folder; the build service will do that for you. In my example for my team project “Slalom.Events”, my drop location is “$/Slalom.Events/Drops”.
- On the Process tab, under “Items to Build” select the .ccproj file that you wish to target with this build definition.
- On the Process tab, add the MSBuild arguments to pass to the cloud project that specify the Publish target (because we want to produce the package) and the desired configuration profile.
- Save the Build Definition and close.
You should now be able to queue a new build for this build definition. When the build completes, verify that the “Drops” folder was created in Source Control and view the contents of your build. You will notice that the binaries were copied to the drop location.
Unfortunately, the “app.publish” folder that contains the .cspkg and .cscfg file for the build is not present. To the best of my knowledge this is because it is produced on the build machine where the bits are compiled, but somehow escapes the copy that occurs to the drop location.
Read on to remedy this issue…
Step 2: Producing the Package and Configuration File
This step outlines a couple small changes you can make to your cloud project file and your build definition to produce the .cspkg and .cscfg files on the build machine. There are probably better ways to accomplish this task, but here is the process that I have used.
First, add a target to our .csproj file to copy the package and configuration file to the drop location when running on a build server.
- In Solution Explorer, Unload your cloud project so you can edit the file manually by right-clicking on the cloud project and selecting “Unload Project”.
- Open the .csproj file in the editor by right-clicking on the cloud project and selecting the edit option.
- Add a target that copies the package and configuration file to the drop location. This target will depend on CorePublish, and contain a condition that will not be met when publishing directly from Visual Studio (so to not interfere with local publishing). Here is an example of that target:
- Save the cloud project file, reload the project, and check-in.
Now that this target exists, we will modify our Build Definition to make sure this target is executed:
- In Team Explorer, right-click on your Build Definition and select “Edit Build Definition…”
- On the Process tab, update the MSBuild Arguments to pass in an argument that will cause the condition of our target to be met, and therefore execute.
- Save and close.
Queue a new build for your build definition. When it completes, navigate to Source Control and view the contents of the build output. You should now see an “app.publish” folder that contains the .cspkg and .cscfg files for your cloud project produced for this build. And, as a bonus, these files are already stored in Source Control for safe keeping.
There are many more customizations that could be made to the cloud build service, but hopefully this gets you started with building your Windows Azure projects.