XL Deploy and TFS 2015 – Building, Importing and Deploying Packages

Recently XebiaLabs released a build task for Microsoft Visual Studio Team Services (VSTS) and Team Foundation Server (TFS) 2015 that facilitates the integration of the vNext build pipeline with their product, XL Deploy. The new build task is capable of creating a deployment archive (DAR package), importing it to an instance of XL Deploy, and eventually, if requested, triggering the deployment of the newly added package. It also contains some other interesting options that will ease the process of versioning the deployment package.

In the following post I will show you how to build an ASP.NET MVC application, create the deployment package, and deploy it via XL Deploy. Let’s start.

Prerequisites

Before we start, make sure that you have all of the necessary items in place. First of all, your build agent needs to be capable of building your application. In the case of on-premises TFS 2015, this means that you need to have installed Visual Studio on your build server.

You also need to install the XL Deploy build task; if you haven’t done so already, refer to Install the XL Deploy build task. As a prerequisite for the XL Deploy build task, your XL Deploy instance needs to be of version 5.0.0 or later; earlier versions are not supported.

Once you ensure that these criteria are met, you can continue reading.

Building your web application

First things first. Create a new empty build definition in your project. If you are not familiar with how to do this, refer to the MSDN article Create a build definition.

Set the repository mappings accordingly before proceeding any further; again, refer to the MSDN article Specify the repository for more information about doing so. For this example I am going to use TFVC; however, all of the techniques I am going to describe do work also with Git repository.

Now you can specify the necessary build steps to compile and publish the web application.

Add a Visual Studio Build build task.

add-task-vsb

Once added, you need to set the necessary parameters. The first mandatory setting is the path to the solution file in source control. Click the button with three dots and locate your solution file in the version control tree. Once found and confirmed, the Solution box will be populated with the correct path. In my case, that is $/XL Deploy Showcase/AwesomeWebApp/AwesomeWebApp.sln. This is the solution that will be built in the build definition.

Next you need to use the MSBuild Arguments setting to indicate that all of the built items should be delivered in the build staging directory. This is an important step because when the XL Deploy build task starts creating the deployment archive (DAR package), it will search for items to include in it, starting from this directory (considering the build staging directory as root). That’s why I am going to set MSBuild Arguments to /p:OutDir=$(build.stagingDirectory). This is a common way for MSBuild to pass a parameter; I’m using a variable that will resolve in a specific path when the build is run. A list of available variables and their usage is explained in the MSDN article Use variables. For now, I will not change any other setting. Make sure that Restore NuGet Packages is selected and that the correct version of Visual Studio is listed.

vsbuild-task

Save the build definition. Enter a relevant name and optionally set the comment.

save-definition

Now, you can test the build. Queue a new build and check the results. If everything went well, you will get a ‘green’ build.

first-build

Now you are sure that the project builds correctly and we can continue with our next task, which is deploying the application via XL Deploy.

You can find more information about build steps on MSDN at Specify your build steps.

XL Deploy build task

In order to continue, you need to have a valid XL Deploy manifest file checked in to our source control. You can read about creating a manifest file at XL Deploy manifest format. I checked in the following manifest:

<?xml version="1.0" encoding="utf-8"?>
<udm.DeploymentPackage version="1.0.0.0" application="AwesomeWebApp">
  <deployables>
	<iis.WebContent name="website-files" file="_PublishedWebsites\AwesomeWebApp">
	  <targetPath>C:\inetpub\AwesomeWebApp</targetPath>
	</iis.WebContent>
	<iis.ApplicationPoolSpec name="AwesomeWebApp">
	  <managedRuntimeVersion>v4.0</managedRuntimeVersion>
	</iis.ApplicationPoolSpec>
	<iis.WebsiteSpec name="AwesomeWebApp-website">
	  <websiteName>AwesomeWebApp</websiteName>
	  <physicalPath>C:\inetpub\AwesomeWebApp</physicalPath>
	  <applicationPoolName>AwesomeWebApp</applicationPoolName>
	  <bindings>
	<iis.WebsiteBindingSpec name="AwesomeWebApp/8088">
	  <port>8088</port>
	</iis.WebsiteBindingSpec>
	  </bindings>
	</iis.WebsiteSpec>
  </deployables>
</udm.DeploymentPackage>

As you can see, I specified the required IIS application pool, a web site, and, most importantly, WebContent. The WebContent element indicates that the files that do represent the web site.

An attribute called file is present on the deployable element iis.WebContent. This attribute is very important, as it will guide the build task in creating the deployment archive. A relative path is set as the value and indicates the folder that needs to be included in the DAR package. This relative path assumes that the root folder is the build staging directory; it will search this directory for the folders specified here. If they are not present, packaging will fail. Now you understand why I delivered the build output in the staging folder. Although this behavior can be overridden in the advanced settings of the XL Deploy build task, I would advise you not to change it if it is not necessary and until you became confident and sufficiently experienced with TFS 2015 builds.

The manifest file also indicates that I expect MSBuild to package the web application under a default folder called _PublishedWebsites. This is standard behavior for MSBuild.

After the manifest file is correctly checked in, you can continue and edit the recently created build definition by adding another build step. This time, go to the Deploy group and select XL Deploy.

add-task-xld

The first mandatory parameter that you need to set is the path to the manifest file. As you did previously for the solution file, click the button with three dots and select the manifest file in source control. In my case, that will be $/XL Deploy Showcase/AwesomeWebApp/deployit-manifest.xml.

Secondly, you need to set the endpoint, which is a definition of the URL and credentials for the XL Deploy server that you intend to use in this deployment. If no XL Deploy endpoints are defined, click Manage and define one. For information about doing so, refer to Add an endpoint in Team Foundation Server 2015. After you are done, click Refresh and your newly added endpoint will appear.

Versioning the package

As you can see, there is a Version option available on the XL Deploy build task. If selected, the deployment package version will be set to the build number format during the process. The build number format is a value that you can set in the General tab of the build definition.

When composing the build number, you can choose between constants and special tokens that are available for that purpose. In Specify general build definition settings, you can read about the available tokens and ways of setting the build number format.

If you are using a different pattern for versioning your deployment package and your build number format has a different use, you can override this behavior by setting a custom value in Version value override parameter under Advanced options.

For this example, I will set this option and then set the build number format to a simple ‘1.1.1$(Rev:.r)’.

Automated deployment

You have the option to automatically deploy the newly imported package to the environment of your choice. If you select the Deploy check-box on the XL Deploy build task, a new field called Target Environment will be available. Here, you need to specify the fully qualified name of the environment defined in XL Deploy. In my case, it is called Test. You can also allow the deployment to be rolled back in case of failure by selecting Rollback on deployment failure.

Note that this requires that you have correctly defined the environment in XL Deploy, with the relevant infrastructure and components. For more information, refer to Create an environment in XL Deploy.

Ready to roll

After you set all of the parameters and save the build definition, you are ready to trigger the new build. Make sure that you set all of the necessary parameters as shown in the picture.

xld-task

You can now trigger the new build. In the build console you should now see the information relevant to the process of creating and versioning the package.

final-build

In case of problems, you can add a new build definition variable named system.debug and set the value to true. Then, in the build log, you will see more detailed messages about all of the actions preformed by the tasks (note that this is not shown in the console). It should be sufficient to diagnose the issue.

Conclusions

This was a small practical example about taking advantage of the new XL Deploy build task. I haven’t covered all of the available options; you can read more about them at Introduction to the Team Foundation Server 2015 plugin. However, this example is sufficient to get started. You can combine other build tasks in your build definition with the XL Deploy build task; but it is important that you invoke the XL Deploy build task after all of the elements that will compose your deployment package are available.

TFS 2015 Build System overview

Introduction

With TFS 2015 a new build system was introduced. If you were using Visual Studio Online you may already have seen it. With TFS 2015 the build system has been completely revamped.

Team Foundation Server has included a build system since its first release. Historically, we started running our builds with XML based MSBuild scripts using a windows service as host. With TFS 2010 a new build system was introduced. It included a more robust infrastructure based on build controllers and agents and the build process was driven by a Workflow Foundation XAML script. Although it had its own limitations and very steep learning curve it was maintained through two versions of TFS, 2012 and 2013. Luckily, with TFS 2015, Microsoft decided to solve major issues of the build system and came up with a new solution. The new build system is finally cross platform and provides more flexibility for infrastructure.

What’s new

A great news for all of you who do not fancy the WWF and XAML (and I’m part of that group), the process is no longer based on it! Infrastructure got simplified and as already mentioned, there is now support for Mac OSX and Linux. On Microsoft website you can find an overview of the new features at https://msdn.microsoft.com/Library/vs/alm/Build/feature-overview

Infrastructure

Some new concepts are introduced into the build infrastructure landscape. There is no longer the necessity for having build controllers and all of the limitations and complexity they brought. Instead, two new concepts are now there to help us with grouping and organizing our build resources. Pool and queues are only “organizational” units and do not require any specific software to be installed or configured.

Pools

A pool is essentially an association of a collection of one or more build agents to one or more queues. Pools are defined at the TFS application tier level. You can create as many pools as you like and you can assign pool administrators to each of them. Different people/groups can be assigned to different pools allowing different groups of people to manage your various build assets.

In synthesis, agent pools are used to organize and define permission boundaries around your build agents.

Queues

Queues are defined at the project collection level and are tied directly to a pool. A queue can be tied to at most one pool; however, a pool can be tied to more than one queue assuming the queues are configured on multiple project collections. As build definitions are created they are associated with a queue. The queue you select for a build definition ultimately limits the set of build agents that can be utilized for the builds generated by that definition.

When you create a new queue you must immediately select the pool that is associated with it. You can also choose to have the queue created and associated with the new pool automatically at the time the pool is created (it’s an option on the new pool dialog).

Agents

The build agent is a small application residing on a build server, a machine that is intended to be used for executing automated builds. The build agents are responsible for building your application (based on the build definitions). Although a pool can be associated with many build agents, a build agent is associated with at most a single pool. With the new build system a Microsoft Cross Platform Build Agent is available and Mac OSX and Linux platforms are supported. We will see later on how to proceed with the installation of a build agent.

The following diagram is a schematic overview of these concepts:

PoolsAndQueues

Build process

Build process has drastically changed. We do not have any more the build process template, which is substituted by a collection of build tasks (steps). In order to define your build process, you will add one or more build tasks in your build definition. By default several build tasks are available as Visual Studio Build, Visual Studio Test and many more. As you can guess, each of them perform an operation in order to accomplish the process you had in mind for your build.

TFS 2015 Build Tasks

More tasks are available online as also all the source code of all the tasks that are available on TFS. You can find a list of the ones supplied by Microsoft at the following address https://msdn.microsoft.com/Library/vs/alm/Build/steps/index and the relevant source code at https://github.com/Microsoft/vso-agent-tasks.

Aside of this important change, there are several things we can benefit of, such as, versioning and real-time output.

Versioning

Build definition versioning and auditing is introduced with the new system so now you can easily see who made the change and exactly what change was made on your build definition. Any change to build definition is logged and you can add a note corresponding to your changes. You can see what changed and revert to the desired version directly from the web interface.

TFS 2015 Build definition history

Real-time output

Some of the most noticeable things about the way that build runs under this new system are the ability to get a real-time visibility while the build runs, which means that we will spend less time trying to dig through logs to see what really happened with your build. You can expect that you will get the same output as your build run locally.

Interface

Unlike the previous version, where you can only make changes to your build definition from Visual Studio, new build definition management is all web based. You do not need any other tool than your web browser in order to create, execute and manage your builds.

Build task anatomy

Every build task is composed from at least a file describing the build task. Describing a task and defining the elements in the interface is done via a predefined structure expressed via a JSON format. At example:

{
   "id": "61ed2e1d-efb7-406e-a31b-81f5d22e6d54",
   "name": "TestTask",
   "friendlyName": "Name that is displayed in the list",
   "description": "Testing new TFS 2015 build system.",
   "category": "Package",
   …

At the bottom of the task file you need to indicate the name of the associated PowerShell script which actually implements the logic of the task itself, or its node .js equivalent in case the task is meant to run cross-platform. If the task should run on both windows and xplat agents, you can indicate both:

"execution": {
   "Node": {
      "target": "ant2.js",
      "argumentFormat": ""
   },
   "PowerShell": {
      "target": "$(currentDirectory)\ant.ps1",
      "argumentFormat": "",
      "workingDirectory": "$(currentDirectory)"
   }
}

Other custom files such as executable can also be shipped with the task. In case you need to localize the task, it can be done by adding the necessary resources. Also you can specify the icon that will represent the task.

Once all of the necessary items are in the folder, you need to zip it and upload to the server. Uploading is done by calling a specific resource on TFS REST API or by utilities provided by Microsoft. Currently only ‘Agent Pool Administrators’ are able to add/update or remove tasks. Tasks are server-wide, this means that you will upload to the server, not to a specific collection or project.

Once you start creating your custom task, the best thing is to check how certain functionalities are implemented by peeking at the source code of the tasks available on GitHub.

TFS 2015 Update 1

As of today, Microsoft started shipping Update 1 for TFS 2015. It brings a couple of things in regard to a build system. With this update, build administrators can now add permissions to agent queue, which will restrict who can use that queue in a build definition. Several new build tasks are added and several minor improvements are present.
For a full list of the improvements you can consult the release notes.

I hope this post gave you an idea about what the new build system brings and made some of the new concepts clearer. If you are not enthusiastic about it maybe the following article could help you getting the right reasons to onboard on TFS 2015 build system.
In the following months I plan to extensively write about TFS 2015 and it’s new build system, bringing several examples from a real life implementation and answers to the questions I got during a training course I held on this argument.

I bet you will enjoy it.

Happy building!