Moving XAML CD builds to vNext

I’m currently in the process of porting a series of Continuous Deployment XAML builds to the new vNext builds. I want to share the ins and outs of doing this and some of the current constraints you can face today while doing this.

Continuous Deployment build passes

I like to break down CD builds into two distinct passes: the build and deploy pass and the test pass.

While building and deploying I prefer to target specific projects, because a lot of times you will see multiple deployment targets in the same solution and these will sometimes have different MSBuild /target’s, so applying a single MSBuild target to a solution will sometimes imply you either route targets in the project files (this is a terrible idea) or you build the same solution multiple times, which can lead to confusion.

While for the test pass it’s preferable to build solutions, otherwise you need to constantly maintain the build definitions as people add more test projects. If folks are following good agile practices they will have 1 test assembly per assembly under test and as folks add assemblies, test assemblies will spawn. If it’s an over-engineered system you will notice assemblies will get created like popcorn popping out in the pot, so if you go down the path of targeting projects in the test pass the amount of maintnance required will be high.

Deployment tasks in vNext

One of the main reasons for us to move to vNext was the fact that now if you wire things properly, you get direct feedback from PowerShell tasks as the new engine is PowerShell driven so it will bubble onto the build logs and summary warnings and errors that PowerShell tasks have. Unlike the previous XAML workflow that would log issues in the text log but wouldn’t bubble out anything.

With this in mind, one of the cool out-of-the-box features of vNext is the amount of deployment tasks that the VSO folks have written for us, so right away you can decommission some of the custom deployment scripts and start using the tasks. If these aren’t really ideal for you, you can get their source from github, tweak them and then publish them again into your collection or project as tweaked versions of the original tasks.

So for example, a given Cloud Service build and deploy pass for us looks like this:

vnext_blog_1.png

Some of the deployment tasks don’t suit our needs, for example we often deploy Azure Web Sites as Web Jobs shells, so what we really care about is the Web Jobs publish process and especially the scheduling pass. The out-of-the-box deployment tasks for Web Sites won’t schedule web jobs.

Build and deployment pass

vnext_blog_2.png

The first 3 are build + deployment tasks for Cloud Services and the last 3 and pure webdeploy build passes for web deployment targets. One of them is actually a pure web deploy into a Web Server IaaS VM pass.

So for web deployments we are actually calling MSBuild with a build /target and then setting the web deployment properties to trigger the packaging and deployment and giving it a publish profile.

The Publish Build artefacts task is a nice addition to the build engine, because we do not allow developers to access any build rigs. This will actually publish the selected artefacts into TFS and they will stay there for as long as the build stays according to what retention policy we have applied to that build definition. So for this specific case, where we are storing Cloud Service packages, the developer can actually download them, unpack and check if a certain file that should be there is actually there.

vnext_blog_3.png

Security wise, because the build artefacts can only be viewed by someone with view permissions on the build, you get to control this. For example for Production builds, you wouldn’t have your developers viewing the builds anyways, so they won’t see the artefacts nor any configuration contained in them.

Test pass

vnext_blog_4.png

Ideally we would be calling a VS Build task for each solution. However, in our current TFS on-premises version (2015 RTM) we have found out that the VS Build task keeps adding a bunch of stuff to the path environment variable each time it runs, so after a while you reach the maximum size for an environment variable and the task will error right away breaking the build. For us this is calling the VS Build task 8 times, if we try the 9th we will get the path error right away.

So we have a single pass that picks up solution on a matching pattern that we, by convention, have set for solutions that contain tests: *.B.sln. Then we run all test passes individually for whatever test passes a given project has. These test passes use Test Traits to pick and filter the tests that should run on them.

We do not usually run Unit Tests, because these are in all Continuous Integration builds, so from a quality point of view the CI pass should have cleared out any issue related to failing Unit Tests by now.

Creating builds that are easily cloned

The first thing you need to do before you fully automate the creation of Release Pipelines is to make sure that creating vNext builds from code doesn’t need to deal with a lot of moving parts.

So ideally, if you can create a CD build for a new environment just by cloning a build and changing its configuration, you’re in a very good space for automation. One of the tricks of achieving this is making sure that everything is aligned, from code to infrastructure, with solution configurations.

So in our case, we align all PaaS components when we create them with in a fully automated way with the configuration names for a project, so if there is a solution configuration called AT, then the Cloud Service for the AT environment will be called sysname-component-AT. Ideally you want a single set of configurations across all branches, so that you have a leaner amount of configurations you need to deal with and so that you prevent in a smooth automated way branches to deploy to environments they shouldn’t be deploying to. However, sometimes folks will resist this idea.

With this in mind, try to use $(BuildConfiguration) as much as possible, for example:

vnext_blog_5.png

vnext_blog_6.png

 

Leave a comment