Using TeamCity and PowerShell to Deploy Automated Builds to Windows Azure

We’re building an ASP.NET MVC3 website that runs in Windows Azure, using the fabulous TeamCity as our build server. So far we have been just building and running the site locally on the build server, but we wanted to extend our build process into the cloud. Here’s what we wanted:

  • Build server runs a build and executes all tests
  • Deploy locally to the build server for our own smoke testing
  • Create Azure packages
  • Deploy to an existing Azure staging environment (retaining the same staging URL so our clients can access it)
  • If staging is all good, we can manually do a VIP-swap to move staging into production.

We found some pretty useful posts, including this one, which got us most of the way along the road. However, even that post seems overly convoluted. There’s no need to execute a cspack command line, for example. Perhaps it’s geared to older versions of the Azure tools? For the record, we’re using MVC3 and Azure tools 1.4, and we have a very basic solution with a single web role, a test project, and an Azure project.

So, assuming you already have a TeamCity build configuration that builds your web project without problems, here’s what you need to do to get your Azure packages built and deployed.

TeamCity Build Step to Create Azure Packages

This one was a lot easier than many blog posts made out. We didn’t need to call cspack via command line. Simply create an MSBuild step, point it at your Azure package (the actual ccproj file), and set the target to be CorePublish. That’s it. Once that step runs, you should see your cspkg file in the output location on your build server.

If you’re struggling with this step, make sure you have the Azure tools installed on your build server, and you might also need to copy across all the MSBuild include files from a PC with Visual Studio on it (from C:\Program Files (x86)\MSBuild\Microsoft\). Worst case you can install Visual Studio on your build server.

Open the little image at right to see an example of how this build step should look.

Create (or copy) a Powershell Script to Deploy to Azure

The first thing to do is install the Windows Azure Platform Powershell Cmdlets on your build server. Just install the package, and remember to run the “StartHere.cmd” file to install and configure the Cmdlets.

This is where we needed to do some jiggery-pokery. The original script we found was rather aggressive. It completely removed the existing staging deployment, then recreated it. The downside of this is that it changes the staging URL. Our modified script is below. This new script assumes an existing staging deployment exists, and will upgrade it. Ideally we should modify the script a tiny bit to deploy a new staging deployment if one doesn’t exist (in the else block).

We’ve also made a small change so that the staging URL is emitted as part of the build script (see the write-host $azureProperties.Url line).

Obviously you’ll need to insert the appropriate certificate thumbprint (you’ve got a management certificate in your Azure console right?!), and your subscription ID. The best way to test that you’ve got this right is to execute the script from the PowerShell command-line on your build server. It took us a few goes to get it bang-on, but once we had everything right, we could see the deploy happening in real-time.

$cert = Get-Item cert:\CurrentUser\My\your-management-certificate-thumbprint
$sub = "your-azure-subscription-id"
$buildPath = $args[0]
$packagename = $args[1]
$serviceconfig = $args[2]
$servicename = $args[3]
$storageservicename = $args[4]
$package = join-path $buildPath $packageName
$config = join-path $buildPath $serviceconfig
$a = Get-Date
$buildLabel = $a.ToShortDateString() + "-" + $a.ToShortTimeString()
 
if ((Get-PSSnapin | ?{$_.Name -eq "AzureManagementToolsSnapIn"}) -eq $null)
{
  Add-PSSnapin AzureManagementToolsSnapIn
}
 
write-host Getting service...
$hostedService = Get-HostedService $servicename -Certificate $cert -SubscriptionId $sub | Get-Deployment -Slot Staging
 
if ($hostedService.Status -ne $null)
{
    write-host Service found.

	$currentService = Get-HostedService $servicename -Certificate $cert -SubscriptionId $sub
 
	write-host Updating staging deployment...
	$currentService 
		| Set-Deployment -slot Staging -package $package -configuration $config -StorageServiceName $storageservicename -label $buildLabel 
		| Get-OperationStatus -WaitToComplete

	$azureProperties = $currentService | Get-Deployment -Slot Staging
	write-host $azureProperties.Url

	write-host Done!

} else {

	write-host Existing staging deployment not found!

}

TeamCity Build Step to Deploy Azure Packages

From there, it’s a simple step to call the script from your build server. Click the image to see how we do it (with placeholder parameters – use your own).

The parameters required in order are:

  • Path to your published package location
  • Package filename (the ones that ends in .cspkg)
  • Service configuration filename (.cscfg)
  • Hosted service name (aka DNS Prefix in Windows Azure console)
  • Storage service name, if this is different to the hosted service name

Done!

There you have it. When you execute this build configuration, you should see the staging deployment being replaced in-line, with zero downtime. If you’ve given your staging URL to client for UAT purposes, they will be able to use this same link and see the updated code as soon as it is deployed. Hooray!

Windows Phone 7: Peeling the Mango

http://www.flickr.com/photos/teagrrl

http://www.flickr.com/photos/teagrrlThe next major release of the Windows Phone OS is still codenamed “Mango”. This morning (New Zealand time), at the MIX conference in Las Vegas, Microsoft has taken the wraps off some the developer details underneath new features in Mango.

The position I take on Mango is this: everyone knows there are features missing from the current version of WP7. Features like multitasking, camera streams, sockets, and more. It would be crazy for Microsoft to not add these high-demand features to WP7 as quickly as possible. This morning we can see that they are certainly adding these features, they’ve thought them through very carefully, and they are further along with implementation than many people predicted.

Update: Here’s a great video from Channel 9 that discusses and demonstrates a bunch of these new features.

So what did we see? Here’s a run-down:

Multitasking: We saw Joe Belfiore demonstrate fast app switching at Mobile World Congress a few months back. Now we’ve seen how developers can take advantage of this, along with some seriously awesome managed background tasks to enable devs to keep apps connected and up to date, without the impact on memory and battery life that is so obvious with “full” multitasking. I can tell you after spending a month with a decent Android phone, one of my most-used apps was a background app killer. Not so with WP7.

IE9 for Windows Phone: HTML5 compliant, GPU accelerated. Finally a first-class mobile browser to consume all of those sites our iPhone loving friends have built.

Additional sensor and runtime access: Additional sensor APIs are being added in WP ‘Mango’, including camera stream access to enable augmented reality scenarios, compass and gyro APIs to enable more advanced detection of motion, and the ability to use socket connections to move beyond HTTP. These are all so “duh” obvious that I won’t go into any more details. Watch the keynote and additional sessions at MIX.

Structured storage: Personally, I’ve been totally happy with serialising my own objects, but for people desperate for a database, Microsoft are adding the ability to package and deploy SQL CE databases onto the Windows Phone platform, and use LINQ to SQL to access the data. Additionally, devs will be able to use contact and appointment APIs to access the user’s address book and calendar on the device (provided the user consents to providing access to the app).

XNA/Silverlight integration: You may not see this now, but this is an absolute killer feature. Any XNA developer will tell you that rendering text (e.g. highscore tables) to the screen is just ugly legwork. With Mango, Microsoft will be breaking down the walls separating Siverlight and XNA, making it easier for developers to build 3D-modeled applications that can overlay Silverlight forms and strings. Think about it: Silverlight’s brilliant XAML layout language, binding, and simple internationalisation story, on top of XNA’s productive 3D environment. Is this not the most developer friendly game platform on the market today?

Tooling investments: Microsoft also demonstrated additional capabilities around the Profiling tooling (initially demoed at PDC10 by Scott Guthrie), as well as showing off new enhancements to the Windows Phone Emulator, allowing developers to manipulate sensor data (i.e., GPS, accelerometer) into the emulator. Slick stuff.

Custom Ringtones: Buried among the 1,500 new API calls are new options for developers to save audio files as custom ringtones. I’m thinking this is a large nod to carriers who make stupid amounts of money from $5 ringtones.

Multiple, and local live tiles: Previous to Mango, the only way to update a custom tile was via a server-based push notification. Not tricky, but a lot of infrastructure overhead for simple apps. Mango now allows developers to update tiles locally (from the aforementioned background agents), and also allows more than one live tile per app. A demonstration showed multiple flight statuses from a travel app, each in their own tile.

So what?

If any of that interests you (and I reckon any self-respecting developer should be interested), have a look at the completely free tools at create.msdn.com. It’s worth a crack right?

WP7 Background Loading with Caliburn and Coroutines

Standing on the shoulders of giants doesn’t even come close. I’m just a hack bringing together some of the wonderful special sauce and ground unicorn horn. This is merely a recipe.

Back in the day (heck, over 6 months ago), Keith Patton pointed to some guidance from Microsoft about the best time to do any heavy-lifting in your Windows Phone 7 apps. The best thing is to wait for the first call to LayoutUpdated after the page has completed navigation. Since then, I’ve also had a good read of Rob Eisenberg‘s simply jaw-dropping documentation around Caliburn Micro. Caliburn Micro is (in my humble opinion), the best MVVM framework for Windows Phone 7, and possibly the best MVVM framework bar none.

[box type=”info”]As if Caliburn wasn’t amazing enough, Rob has responded to my original post and given some brilliant tips that resulted in a bunch of refactoring. You get to see the final product.[/box]

Until we get C# 5 on the phone, Rob’s coroutines are a pretty damn sweet way to bring together multiple asynchronous calls in a very tidy syntax. The heavy-lifting we need to do in a WP7 page load almost invariably involves async calls to load data (especially after tombstoning), plus some user notification. Coroutines eat this stuff for breakfast.

So how do we roll this all together? What I wanted was a way for any given page to do this:

  1. Load up and bind to the relevant view model;
  2. All pages should implement the “After first layout updated” pattern;
  3. If the page’s view model knows about my heavy-lifting paradigm, then use it;
  4. Do it sexily with coroutines, which keeps the code tidy and helps us with user notifications in asynch-world.

Step 1

Use Caliburn Micro. It’s just that easy. If you’re still manually setting DataContext in your XAML pages (without a good reason), you’re doing it wrong.

Step 2

To make sure all my pages implement the pattern, I created a custom FrameAdapter based on the Caliburn one. Previously I had used a custom base page, but going the FrameAdapter route means we don’t have to munge the machine generated xaml when we create a new page.

There’s a couple of interesting bits in here:

  • On the Frame’s navigated override, we hook up the Content’s LayoutUpdated event. The content of the frame is our xaml view.
  • We check if the pages’s DataContext is IFirstLayoutAware.
  • We use the brand-new Action.Invoke method from Caliburn Micro, which creates and execution context for us, then executes the named method (which we’ve defined as required in IFirstLayoutAware.)
public class LayoutAwareFrameAdapter : FrameAdapter 
{
	private bool _onNavigatedToCalled;
	private readonly Frame _frame;

	public LayoutAwareFrameAdapter(Frame frame, bool treatViewAsLoaded = false) : base(frame, treatViewAsLoaded)
	{
		_frame = frame;
	}

	protected override void OnNavigated(object sender, NavigationEventArgs e)
	{
		var fe = e.Content as FrameworkElement;
		if (fe != null)
		{
			fe.LayoutUpdated += PageLayoutUpdated;
		}
		_onNavigatedToCalled = true;
		base.OnNavigated(sender, e);
	}

	void PageLayoutUpdated(object sender, EventArgs e)
	{
		var fe = _frame.Content as FrameworkElement;

		if (fe == null || fe.DataContext == null)
			return;

		if (_onNavigatedToCalled && (fe.DataContext is IFirstLayoutAware))
		{
			_onNavigatedToCalled = false;

			var dc = fe.DataContext as IFirstLayoutAware;
			Action.Invoke(dc,"AfterLayoutFirstUpdated",fe,fe);
		}
	}

}

To take advantage of this custom frame adapter, we need only inject it in our Caliburn Bootstrapper, in place of the default FrameAdapter. I’m using Ian Randall’s MicroIoc container here. Line 12 is the only change required to wake up the functionality in the class above.

public class AppBootstrapper : PhoneBootstrapper
{
	IMicroIocContainer container;

	protected override void Configure()
	{
		TiltEffect.SetIsTiltEnabled(RootFrame, true);

		container = new MicroIocContainer()
			.Register<MainPageViewModel>("MainPageViewModel")
			.Register<ItemListViewModel>("ItemListViewModel")
			.Register<ItemDetailViewModel>("ItemDetailViewModel")
			.Register<PlaceBidViewModel>("PlaceBidViewModel")
			.RegisterInstance<INavigationService>(new LayoutAwareFrameAdapter(RootFrame), null)
			.RegisterInstance<IPhoneService>(new PhoneApplicationServiceAdapter(PhoneService), null);
	   
	}
	
	[...]
}

Step 3

You would have seen the IFirstLayoutAware interface in the previous step. This is just a tiny interface that defines the behaviour required of View Models that will take advantage of our performance approach:

public interface IFirstLayoutAware
{
	IEnumerable<IResult> AfterLayoutFirstUpdated();
}

The IEnumerable<IResult> type will be familiar if you’ve read the documentation around Coroutines. I you haven’t, you need to do so right now before you read on. I’ll wait.

Step 4

So, within any of your View Models that implement IFirstLayoutAware you need to implement that special method. How you do it will depend on how you’ve chosen to divide up the loading behaviour for your application, but here’s mine for the first page of my Silent Auction app:

public class MainPageViewModel : BusyIndicatorViewModelBase, IFirstLayoutAware
{
	[...]

	public IEnumerable<IResult> AfterLayoutFirstUpdated()
	{
		using (this.Block("Loading Auction Settings..."))
		{
			yield return new LoadSettings(SettingsAction.GetApiHost);
			yield return new LoadSettings(SettingsAction.GetSettings);
		}
		
		_canBrowseItems = true;
		//ping all properties
		Refresh();
		// can do this after page is visible...
		yield return new LoadAuctionItems();
	}
}

Isn’t it gorgeous? Those yield returns are sent to Caliburn’s Action pipeline, and executed in turn. There’s a lot of custom code behind each one, but just quickly:

  • LoadSettings does some asynchronous calls to a web API to get some basic information.
  • Once LoadSettings is complete, we can turn off the loading message and refresh some data on the page via Refresh(); (e.g. links to brand images that we have just loaded from settings).
  • LoadAuctionItems is less urgent (we need it for the next page), so it can happen last, and just chug away in the background while the user is thinking.

Remember that all of the guidance around Silverlight and WP7 still apply. Inside those IResult objects we should be using proper asynchronous coding – don’t block on web requests; marshall callbacks to the UI thread; and all that good stuff.

The using(this.Block(..)){} pattern is another gem from Rob Eisenberg. Block is an extension method that returns a DisposableAction, which in itself is a sweet little pattern. It says “give me an object that will execute a defined action when it is disposed”:

public class DisposableAction : IDisposable
{
	Action _action;

	public DisposableAction(Action action)
	{
		if (action == null)
			throw new ArgumentNullException("action");
		_action = action;
	}

	public void Dispose()
	{
		_action();
	}
}

So in our particular case of using (this.Block(“Loading Auction Items…”)) we’re saying “set a busy message, and when I’m finished, clear it out.” The Block extension method is below.

public static class BusyExtensions
{
	public static IDisposable Block(this IBusyIndicator indicator, string message)
	{
		indicator.ShowBusy(message);
		return new DisposableAction(() => indicator.HideBusy());
	}
}

Your view models that want to show busy messages need to implement IBusyIndicator, which is something a bit like this:

public interface IBusyIndicator
{
	void ShowBusy(string message);
	void HideBusy();

	bool IsBusy { get; set; }
	string BusyMessage { get; set; }
}

Conclusion

Like I said at the start, this is just a recipe, made up of many parts magical Caliburn fairy dust, and some special sauce. You’ll need to understand MVVM and Caliburn to really make the most of it. Let me know if you like it.

Tech.Ed

As far as pinnacles go, it doesn’t get much more rocky and steep than Tech.Ed, at least in the New Zealand Microsoft development world. So I’m rather stoked to be presenting not one, but two sessions at Tech.Ed this year. If it goes well, it may just top that time Scott Hanselman (Google vanity bait ahoy!) commented on my StackOverflow answer for highlights of my development career.

If you can’t make it to Tech.Ed (I believe it is all but sold out), you could have a crack at Code Camp on the Sunday before (29th August), which is completely free. The downside is you’ll need to avoid Keith Patton and myself presenting yet more Windows Phone 7 content. Or you could come along and heckle to get your money’s worth?

Back to Tech.Ed (I think of it like PhysEd but a lot less horrible). I’ll be presenting one session on the Windows Phone Marketplace, including how to make enough money to wallpaper your house with; and a second session on the free developer tools (Visual Studio Express and Expression Blend), with a focus on the schizophrenic designer/developer nature of most one-man development teams.

If you want the official line on those sessions, look up my name in the session list over here, or read below:

Hardhat vs Beret – Making use of Windows Phone 7 Development and Design Tools

Track: Windows Phone Development
Speaker(s): Ben Gracewood
Do you wear a hardhat, a beret, or both? The free Windows Phone 7 software development kit comes with both Visual Studio Express 2010 and Expression Blend 4. So which is the right tool for the job? This session will cover the capabilities of both tools, highlight their strengths and weaknesses, and teach you about Developer/Designer interaction – even if these are one in the same person.

Shake Your Moneymaker: Marketing and Selling Windows Phone 7 Applications

Track: Windows Phone Development
Speaker(s): Ben Gracewood, Mark Bishop
How do you make money from Windows Phone 7 applications? In this session Mark and Ben will tell you everything there is to know about marketing and selling applications for Windows Phone 7. The session includes walkthroughs of the Marketplace from a developer and customer perspective, along with some essential application marketing tips and tricks. We’ll dissect some million-dollar examples from other platforms, and tell you how it’s done.

See you there!

Integrated Links and Styling for Windows Phone 7 WebBrowser Control

The situation: you need to display nicely formatted HTML in your Windows Phone 7 application. You want the formatting of this HTML to match the system theme, and that formatting to respect the user’s theme selections. So, for example, if the user changes their “highlight” theme colour, the links in the HTML should use this colour. You also want links in that HTML to open the full Internet Explorer browser.

Replicating the system theme

Let’s get down to business. What we need is a generated stylesheet that we can apply to our HTML strings so that they are formatted just like the system style. We can leverage the built-in styles to do this. I created a WebBrowserHelper class, and it has a couple of methods to create the style and layout that I need. First we create the HTML head block:

public static string HtmlHeader(double viewportWidth)
 {
 var head = new StringBuilder();

head.Append("<head>");
 head.Append(string.Format(
 "<meta name=\"viewport\" value=\"width={0}\" user-scalable=\"no\">",
 viewportWidth));
 head.Append("<style>");
 head.Append("html { -ms-text-size-adjust:150% }");
 head.Append(string.Format(
 "body {{background:{0};color:{1};font-family:'Segoe WP';font-size:{2}pt;margin:0;padding:0 }}",
 GetBrowserColor("PhoneBackgroundColor"),
 GetBrowserColor("PhoneForegroundColor"),
 (double)Application.Current.Resources["PhoneFontSizeNormal"]));
 head.Append(string.Format(
 "a {{color:{0}}}",
 GetBrowserColor("PhoneAccentColor")));
 head.Append("</style>");
 head.Append(NotifyScript);
 head.Append("</head>");

return head.ToString();
}

You can see we’re using the Segoe WP system font, and accessing some of the resources like PhoneBackgroundColor to make sure this color changes correctly when the phone style changes. Also, we’re using the meta viewport to set tell the browser when to wrap text. You may need to fiddle the -ms-text-size-adjust:150% to get the text size perfect, depending on the width of your WebBrowser Control.

If you’re wondering about the NotifyScript bit, I’ll explain later.

You’ll notice I need to munge the Silverlight colour resources to get a web-format colour out. I drop the alpha channel from the string using this helper method:

private static string GetBrowserColor(string sourceResource)
{
var color = (Color)Application.Current.Resources[sourceResource];
return "#" + color.ToString().Substring(3, 6);
}

The next step is to create the full html document when we just have an html string (e.g. “This is <b>bold</b>”:

public static string WrapHtml(string htmlSubString, double viewportWidth)
{
var html = new StringBuilder();
html.Append("<html>");
html.Append(HtmlHeader(viewportWidth));
html.Append("<body>");
html.Append(htmlSubString);
html.Append("</body>");
html.Append("</html>");
return html.ToString();
}

Now we can use these helper methods to pass our little basic html string to the WebBrowser control and have it rendered perfectly matching the system theme. Somewhere in the Page_Load or similar:

var fullHtml = WebBrowserHelper.WrapHtml(
"My little html string with <b>bold</b> text",
WebBrowser1.ActualWidth);
WebBrowser1.NavigateToString(fullHtml);

Bear in mind that we will need to reload the WebBrowser content when the theme changes. It would be safest to re-call NavigateToString when our app comes back from Obscured or Deactivated, in case the user went off to the settings panel and changed their theme.

Handling links

We have one other problem. If your HTML has links in it, these links will open with in the WebBrowser control when clicked. We need to catch those clicks and use the WebBrowserHelper control to open them in the full mobile Internet Explorer. The solution to this is in two parts: some javascript to catch all links and send them to the WebBrowser’s containing control (window.external.notify); and the event to handle these clicks.

The critical first step is to make sure our WebBrowser control is allowed to run scripts by setting IsScriptEnabled=”True”. If you don’t do this, nothing below will work.

Part one: this script adds an “onClick” event to every single A tag in the document, and sends the link URL as a message to the WebBrowser’s control. It uses a sneaky bit of javascript to find every A tag and add an onclick event that cancels the original hyperlink click.

public static string NotifyScript
{
get
{
return @"<script>
window.onload = function(){
a = document.getElementsByTagName('a');
for(var i=0; i < a.length; i++){
var msg = a[i].href;
a[i].onclick = function() {notify(msg);};
}
}
function notify(msg) {
window.external.Notify(msg);
event.returnValue=false;
return false;
}
</script>";
}
}

Part two: we need to handle the ScriptNotify event of the WebBrowser control, and simply launch the external browser using the URL we have been passed from the HTML’s A tag.

private void WebBrowser1_ScriptNotify(object sender, NotifyEventArgs e)
{
WebBrowser1.Dispatcher.BeginInvoke(
() => WebBrowserHelper.OpenBrowser(e.Value)
);
}
...
public static void OpenBrowser(string url)
{
WebBrowserTask webBrowserTask = new WebBrowserTask { URL = url };
webBrowserTask.Show();
}

So there you have it. Pass an HTML string (with as much HTML formatting as you want: bold, italics, numbered lists – go to town!) to the WrapHtml helper, and you’ll have an integrated, system-formatted WebBrowser control that handles links properly. Nice!

Download sample code.