TFS Build vNext – A Preview

Currently, Microsoft is working hard on a complete rewrite of the TFS Build system. They announced this, among other things, at the Connect event back in November and did a short demo of it. It is not yet available, but as part of the MVP program, a few of us has now been fortunate enough to get access to an early preview of the new build system.

Note: This version is in pre-alpha state, meaning that a lot of things can and will change until the final version!

Microsoft will enable a beta version to a broader public on Visual Studio Online later on this year, and it will RTM in TFS 2015. I will write a series of blog posts about Build vNext as it evolves. In this first post I will take a quick look at how to create and customize build definitions and running them in the new Web UI.

Key Principals

The key principals of TFS Build vNext are:

  • Customization should be dead simple. Users should not have to learn a new language (Windows Workflow anyone?) in order to just run some tool or script as part of the build process
  • Provide a simple Web UI for creating and customizing build definitions. No need for Visual Studio to customize builds anymore.
  • Support cross platform builds (Linux, MacOS…)  As in most other areas right now, Microsoft is serious about supporting other platforms than Windows, and TFS Build won’t be an exception.
  • Sharing build infrastructure. The concept of a build controller tied to a collection is gone, instead we will create agent pools at the deployment level and connect agents to those.
  • Don’t mess with the build output and keep my logs clean. One of the most frustrating things about the current version of TFS Build is that by default it doesn’t preserve the output structure of the compiled projects, but instead places them beneath a common Binaries directory. This causes all sort of problems, such as post build events that are dependent on relative path etc.

    CI build == Dev build !

  • Work side by side with the existing build system. All your existing XAML build definitions will continue to work just like before, and you will be able to create new ones. But don’t expect anything to be added in terms of functionality to the XAML builds

 

Creating a build definition in vNext

In this post, I will show how easy it is to create a  new build definition in Build vNext, and customize it to update the version info in all the assembly files using a PowerShell task with a custom script.

Note: There will probably be a versioning task out of the box in the final release, but currently there isn’t.

Let’s get started:

  1. From the dropdown, you can select from a list of build definition templates. These templates are created by saving an existing build definition as a template. Currently, they are scoped to the team project level: 

    image

    Here I’m going to select the Visual Studio definition template.

  2. This results in a build definition with two tasks, one that compiles the solution and one that runs all the unit tests using the Visual Studio test runner task

    image 

  3. Selecting a task shows the properties of that task to the right, the properties of the Visual Studio Build task is shown above. Some of these properties are typed, meaning that for example the Solution property let’s you browse the current repository to select a solution. By default, it will locate all solution files and compile them (using the ***.sln pattern)

    You can also see that the Platform and the Configuration property uses the variables $(platform) and $(config). We will come back to them shortly.

  4. The first thing we want to do typically is specifying which repository that the build will download the source from. To do this, select the Repository tab:

    image

    Looking at the Repository type field, since this is a Git team project it will let me choose either Git (which means a git repo in the current team project) or GitHub, which actually lets me choose any Git repo. In that case I will need to enter credentials as well. When selecting the Git repo type, i can then select the repo (Visual Studio ALM in this case) from the current team project, and then I can select the default branch in a drop down.

  5. If you want to add more tasks to the definition, go back to the Build tab and click on the Add new task link. This will display a list of all available tasks, shown below:

    image

    The list of tasks here are of course not complete, but as you can see there are a lot of cross platform tasks there already. To add a task to the build definition,  select it and press Add.
    Here, I will select the PowerShell task that I will use to version all my assemblies:

    image 

    When adding a new task it will end up at bottom of the task list, but you can easily reorder the tasks by using drag and drop. Since I must stamp the version information before i compile my solution, I have dragged the PowerShell task to the top. This task then requires me to select a PowerShell file to execute, and I also specified a working folder since the script I am using assumes this. All paths here are relative to the repository.

    Note: Although currently not possible, it will be possible to rename the build tasks

  6. On the Triggers tab, the only option available right now is to trigger the build on every check-in (or push in the case of Git). I can also select to batch the changes, which is the same thing as the Rolling build trigger in the existing version of TFS build.
    This means that all changes that are checked in during a running build will be batched up and processed in the next build as soon as the current build has completed.

    In addition we can specify one or more branches that should trigger this build.

     image

    Tip: The filter strings can include * as a filter, which lets me for example specify refs/heads/feature* as a filter that will trigger on any change on any branch that starts with the string feature.

  7. On the Variables tab, we can specify and add new variables for this build definition. Here you can see the config and platform variables that were referenced in the Build tab:

    image

  8. Last, let’s take a look at the Options tab. The MultiConfiguration option enables us to build the selected solution(s) multiple times, each time for every combination of the variables that are specified here. By default, it will list the config and platform variables here. So, this means that the build will first build my solution using Debug | Any CPU, and the it will compile it using Release | Any CPU.

    If I check the Parallel checkbox, it will run these combinations in parallel, if there are multiple agents available of course.

    image

    Also, we can enable copy to Staging and Drop location here. The build agent will copy everything that matches the Search pattern and place it in the staging folder

  9. Finally, let’s save the new build definition. Note that you can also add a comment every time you save a build definition:

    image

    These comments are visible on the History tab, where you can view the history of all the changes to the build definition and view the changes between any of the changes. Nice!

 

Running a Build

The build definition is complete, let’s kick off a build. Click on the Queue build.. button at the top to do this. This will show the live output of the build, both in a console output window and in an aggregated view where the status of each task is shown:

image

 

Here you can note several nice features of build vNext:

  • The console output shoes the exact output from each task, just like it would if you ran the same command on your local machine
  • The aggregated view to the left shows the status and progress of every task which makes it very clear how far in the process the build is
  • This view also show parallel builds, in this case I have enabled the MultiConfiguration option and have two build agents configured, meaning that both Debug|AnyCPU and Release|AnyCPU are being processed in parallel on separate agents.
  • If you select one of the tasks to the left, you will see the build output for this particular task

 
When the build completes, you will see a build summary and you can also view a timeline of the build where the duration of each task is shown:

 

image

Trigger Visual Studio Release Management vNext from TeamCity

The last couple of updates to Visual Studio has included a lot of new functionality for Visual Studio Release Management. The biggest one is the introduction of so called vNext releases, that leverages Powershell DSC for carrying out the provisioning and deployments of environments and applications.

Also included in Visual Studio 2013 Update 3 was the introduction of a REST API that allows us to both trigger new releases and read back information about them. This API is only available for vNext release templates, and will probably not be implemented for the “old” agentbased deployments.

This REST API opens up a lot of integration possibilities, for example we don’t have to use TFS Build to automatically trigger a release. In this post, I will show how we can use the popular TeamCity build server from JetBrains to trigger a release as part of the build.

 
First of all, we need to setup a release template in Visual Studio Release Management. I won’t go through all the details here, the most important once is that the components that we define must use the UNC Path as the source parameter:

image

Here I have specified a shared folder, \localhostbuildoutput. Beneath this path, VSRM will look for a folder that typically correspond to a build number that we will pass in using the API, as you will see later on.

Next, we create our release template. To be able to trigger a build using the API, make sure that you tick the “Can trigger a release from a Build?” checkbox:

 image

 

Then we define our deployment sequence, in this case I just have one action for deploying my web site using a PowerShell script:

SNAGHTML5c6e9ead

There is nothing really nothing special here, I refere to the DeployWebSite.ps1 which is a PowerShell DSC script that installs my web site. I have also a DestinationPath variable that is referenced in the DSC script and specifies where the web site should be installed on the server.

 

Now, to trigger a release of this release template we are going to use a PowerShell script, that we can execute using TeamCity. I have used a sample from Microsoft and modified it to use parameters.

Here is the full script:

 

param( [string]$rmServer, [string]$rmUser, [string]$rmPassword, [string]$rmDomain, [string]$releaseDefinition, [string]$deploymentPropertyBag ) $deploymentPropertyBag = $propertyBag = [System.Uri]::EscapeDataString($deploymentPropertyBag) $exitCode = 0 trap { $e = $error[0].Exception $e.Message $e.StackTrace if ($exitCode -eq 0) { $exitCode = 1 } } $scriptName = $MyInvocation.MyCommand.Name $scriptPath = Split-Path -Parent (Get-Variable MyInvocation -Scope Script).Value.MyCommand.Path Push-Location $scriptPath $orchestratorService = "http://$rmServer/account/releaseManagementService/_apis/releaseManagement/OrchestratorService" $status = @{ "2" = "InProgress"; "3" = "Released"; "4" = "Stopped"; "5" = "Rejected"; "6" = "Abandoned"; } #For Update3 use api-version=2.0 for Update4 use api-version=3.0. $uri = "$orchestratorService/InitiateRelease?releaseTemplateName=" + $releaseDefinition + "&deploymentPropertyBag=" + $propertyBag + "&api-version=3.0" $wc = New-Object System.Net.WebClient #$wc.UseDefaultCredentials = $true # rmuser should be part rm users list and he should have permission to trigger the release. $wc.Credentials = new-object System.Net.NetworkCredential("$rmUser", "$rmPassword", "$rmDomain") try { $releaseId = $wc.UploadString($uri,"") $url = "$orchestratorService/ReleaseStatus?releaseId=$releaseId" $releaseStatus = $wc.DownloadString($url) Write-Host -NoNewline "`nReleasing ..." while($status[$releaseStatus] -eq "InProgress") { Start-Sleep -s 5 $releaseStatus = $wc.DownloadString($url) Write-Host -NoNewline "." } " done.`n`nRelease completed with {0} status." -f $status[$releaseStatus] } catch [System.Exception] { if ($exitCode -eq 0) { $exitCode = 1 } Write-Host "`n$_`n" -ForegroundColor Red } if ($exitCode -eq 0) { "`nThe script completed successfully.`n" } else { $err = "Exiting with error: " + $exitCode + "`n" Write-Host $err -ForegroundColor Red } Pop-Location exit $exitCode

Basically, this script calls the following REST API endpoint:

http://RMSERVER/account/releaseManagementService/_apis/releaseManagement/OrchestratorService/InitiateRelease?releaseTemplateName=RELEASEDEFINITION&deploymentPropertyBag=PROPERTYBAG&api-version=3.0 

 

This REST endpoint returns a release id, which we can use to read the status of the release. The script loops until the status is not “In Progress” and the quits and returns an exit code depending on how the release went.

 

The parameters of the above endpoint are:

  • RMSERVER

    The URL including port to the release management server, typically somthing like contoso.com:1000 

  • RELEASEDEFINITION

    The name of the release template that we want to trigger.

  • PROPERTYBAG

    Now this one is a bit special. This is an array of key/value which is not yet documented but it typically looks like this:

  • { "Component1:Build" : "Component1Build_20140814.1", "Component2:Build" : "Component2Build_20140815.1", "ReleaseName" : "$releaseName" }

    The first two lines references two different components in RM. Here I have just called them Component1 and Component2. The :Build is a keyword and must be there. The value part is the build number, which RM will append to the UNC path that we defined earlier. Note that we can use different build numbers per component here if we want to.

    The last line is a predefined keyword that allows us to specify the name of the release, something that we actually can’t do using the RM client or the standard RM TFS Build release template so this is a nice feature.

 

So, to execute this script in TeamCity, add the above script to repository and then add a PowerShell build step at the end of your build in TeamCity that looks something like this:

image 

 

The Script Arguments property is the tricky part, since we have to escape the quotes for the propertyBag parameter, and we will also use the %env:BUILD_NUMBER% variable from TeamCity for the build number. Here is the full string as an example:

-rmServer SERVER:1000 -rmUser USER -rmPassword PASSWORD -rmDomain DOMAIN -releaseDefinition VSGallery -deploymentPropertyBag “{“VSGallery Web Application:Build” : “%env.BUILD_NUMBER%”,”ReleaseName” : “%env.BUILD_NUMBER%”}”

 

Running this build in TeamCity will now trigger a release in Release Management:

image

Copy TFS Build Definitions between Projects and Collections

The last couple of years it has become apparent that using multiple team projects in TFS is generally a bad idea. There are of course exceptions to this, but there are a lot ot things that becomes much easier to do when you put all of your projects and team in the same team project.

Fellow ALM MVP Martin Hinshelwood has blogged about this several times, as well as other people in the community. In particular, using the backlog and portfolio management tools makes much more sense when everything is located in the same team project.

Consolidating multiple team projects into one is not that easy unfortunately, it involves migrating source code, work items, reports etc.  Another thing that also need to be migrated is build definitions. It is possible to clone build definitions within the same team project using the TFS power tools.

The Community TFS Build Manager also lets you clone build definitions to other team projects. But there is no tool that allows you to clone/copy a build definition to another collection. So, I whipped up a simple console application that let you do this.

The tool can be downloaded from

https://onedrive.live.com/redir?resid=EE034C9F620CD58D!8162&authkey=!ACTr56v1QVowzuE&ithint=file%2c.zip

 

Using CopyTFSBuildDefinitions

You use the tool like this:

CopyTFSBuildDefinitions  SourceCollectionUrl  SourceTeamProject  BuildDefinitionName  DestinationCollectionUrl  DestinationTeamProject [NewDefinitionName]


Arguments

  • SourceCollectionUrl
    The URL to the TFS collection that contains the team project with the build definition that you want to copy
  • SourceTeamProject
    The name of the team project that contains the build definition
  • BuildDefinitionName
    Name of the build definition
  • DestinationCollectionUrl
    The URL to the TFS collection that contains the team project that you want to copy your build definition to
  • DestinationTeamProject
    The name of the team project in the destination collection
  • NewDefinitionName (Optional)
    Use this to override the name of the new build definition. If you don’t specify this, the name will the same as the original one
  • Example:

    CopyTFSBuildDefinitions  https://jakob.visualstudio.com DemoProject  WebApplication.CI https://anotheraccount.visualstudio.com
     
     

    Notes

    • Since we are (potentially) create a build definition in a new collection, there is no guarantee that the various paths that are defined in the build definition exist in the new collection. For example, a build definition refers to server paths in TFVC or repos + branches in TFGit. It also refers to build controllers that definitely don’t exist in the new collection. So there will be some cleanup to do after you copy your build definitions. You can fix some of these using the Community TFS Build Manager, for example it is very easy to apply the correct build controller to a set of build definitions

    • The problem stated above also applies to build process templates. However, the tool tries to find a build process template in the new team project with the same file name as the one that existed in the old team project. If it finds one, it will be used for the new build definition. Otherwise is will use the default build template

    • If you want to run the tool for many build definitions, you can use this SQL scripts, compliments of Mr. Scrum/ALM MVP Richard Hundhausen to generate the necessary commands:

      USE Tfs_Collection

      GO

      SELECT ‘CopyTFSBuildDefinitions.exe http://SERVER:8080/tfs/collection “‘ + P.ProjectName + ‘” “‘ + REPLACE(BD.DefinitionName,”,”) + ‘” http://NEWSERVER:8080/tfs/COLLECTION TEAMPROJECT’

        FROM tbl_Project P

             INNER JOIN tbl_BuildGroup BG on BG.TeamProject = P.ProjectUri

             INNER JOIN tbl_BuildDefinition BD on BD.GroupId = BG.GroupId

        ORDER BY P.ProjectName, BD.DefinitionName

     

    Hope that helps, let me know if you have any problems with the tool or if you find it useful

TFS Build: NuGet.exe was not found in the expected location

Problem

One of our customers recently had a problem with NuGet restore when they created a new build template, based on the standard TfvcTemplate.12.xaml template. In TFS 2013, package restore is done automatically by the default build templates.

It is configured as part of the RunMSBuild activity, where you can enable and disable this by setting the EnableNuGetPackageRestore property:

image

 

However, when we were executing the builds we got the following warning in the build log:

Unable to restore NuGet packages. Details: NuGet.exe was not found in the expected location: C:UsersBuildAppDataLocalTempBuildAgent18Assembliesnuget.exe

This error puzzled us quite a bit. NuGet.exe is installed as part of TFS Build and is located in the %ProgramFiles%/Microsoft Team Foundation Server 12.0/Tools folder. Why was Team Build looking in the build agent custom assembly folder?

It turns out that the reason for this was that the customer had not only checked in the custom activity assemblies in TFVC, they had also checked in all the references TFS assemblies (such as Microsoft.TeamFoundation.Build.Workflow.dll for example). This is not necessary, but had until now never caused any problems. But now, since this assembly was used during the build, it looked in the current path of the assembly for NuGet.exe which resolved to the path from the error message above.

Solution

After removing all the TFS assemblies from version control NuGet package restore started working again.

Creating a Build Definition using the TFS 2013 API

Almost four years ago I wrote a post on how to create a build definition programmatically using the TFS 2010 API. The code is partyl still valid, but since a lot of the information in a build definition is dependent on the build process template, the code in the blog
does not work properly for the TFS 2013 default build templates. In addition, since the introduction of Git in TFS 2013, there are some other differences in how you create a build definition for a Git team project compared to a TFVC team project.

So, in this post I will show an updated version of the code for creating a build defintion. I will actually show two samples, one for the GitTemplate.12.xaml and one for the TfvcTemplate.xaml which are the default template used in TFS 2013.

 

Creating a Git Build definition (GitTemplate.12.xaml)

Here is the code for creating a build definition using the GitTemplate.12.xaml build process template
//Create build definition and give it a name and desription
IBuildDefinition buildDef = buildServer.CreateBuildDefinition(tp);
buildDef.Name = "ATestBuild";
buildDef.Description = "A description for this build defintion";
buildDef.ContinuousIntegrationType = ContinuousIntegrationType.Individual; //CI

//Controller and default build process template
buildDef.BuildController = buildServer.GetBuildController("Hosted Build Controller");
var defaultTemplate = buildServer.QueryProcessTemplates(tp).First(p => p.TemplateType == ProcessTemplateType.Default);
buildDef.Process = defaultTemplate;

//Drop location
buildDef.DefaultDropLocation = "#/";    //set to server drop

//Source Settings
var provider = buildDef.CreateInitialSourceProvider("TFGIT");
provider.Fields["RepositoryName"] = "Git";
provider.Fields["DefaultBranch"] = "refs/heads/master";
provider.Fields["CIBranches"] = "refs/heads/master";
provider.Fields["RepositoryUrl"] = url + "/_git/Git";
buildDef.SetSourceProvider(provider);

//Process params
var process = WorkflowHelpers.DeserializeProcessParameters(buildDef.ProcessParameters);

//What to build
process.Add("ProjectsToBuild", new[]{"Test.sln"});
process.Add("ConfigurationsToBuild", new[]{"Mixed Platforms|Debug"});

//Advanced build settings
var buildParams = new Dictionary<string, string>();
buildParams.Add("PreActionScriptPath", "/prebuild.ps1");
buildParams.Add("PostActionScriptPath", "/postbuild.ps1");
var param = new BuildParameter(buildParams);
process.Add("AdvancedBuildSettings", param);

//test settings
var testParams = new Dictionary<string, object>
                                 {
                                     { "AssemblyFileSpec", "*.exe" },
                                     { "HasRunSettingsFile", true },
                                     { "ExecutionPlatform", "X86" },
                                     { "FailBuildOnFailure", true },
                                     { "RunName", "MyTestRunName" },
                                     { "HasTestCaseFilter", false },
                                     { "TestCaseFilter", null }
                                 };

var runSettingsForTestRun = new Dictionary<string, object>
                                            {
                                                { "HasRunSettingsFile", true },
                                                { "ServerRunSettingsFile", "" },
                                                { "TypeRunSettings", "CodeCoverageEnabled" }
                                            };
testParams.Add("RunSettingsForTestRun", runSettingsForTestRun);

process.Add("AutomatedTests", new[]{ new BuildParameter(testParams)});
            
//Symbol settings
process.Add("SymbolStorePath", @"\serversymbolssomepath");

buildDef.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(process);

//Retention policy
buildDef.RetentionPolicyList.Clear();
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Succeeded, 10, DeleteOptions.All);
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Failed, 10, DeleteOptions.All);
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Stopped, 1, DeleteOptions.All);
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.PartiallySucceeded, 10, DeleteOptions.All);

//Lets save it
buildDef.Save();

 

Some things to note here:

  • The IBuildDefinitionSourceProvider interface is new in TFS 2013, and the reason for it is of course to abstract the differences between TFVC and Git source control. As you can see, we use the “TFGIT”

    to select the correct provider, and then we use the Fields property to populate it with information

  • The process parameters are created by using dictionaires, with the corresponding key and values. If you are familiar with the GitTemplate.12.xaml, you will recognize the name of these parameters.
  • As for drop locations, in TFS 2013 you can select between no drop location, a drop folder (share) or a server drop, which means the output is stored inside TFS and accessible from the web access.

    In the sample above, we specify #/ which (not that obvious) means a server drop. If you want to use a share drop location, just specify the server path for the DefaultDropLocation

 

Creating a TFVC Build definition (TfvcTemplate.12.xaml)

AS it turns out, creating a TFVC build definition using the TfvcTemplate.12.xaml is almost identical, since the build team went to great effort and abstracted away most differences. The only difference in fact, at least when it comes to the most common settings is how you define the workspace mappings. And this code is the same as it was in TFS 2010/2012. In addition, you don’t need to create a source provider, because there is nothing that needs to be configured other than the workspace.

 

Here is the full sample for TFVC:

//Create build definition and give it a name and desription
IBuildDefinition buildDef = buildServer.CreateBuildDefinition(tp);
buildDef.Name = "ATestBuild";
buildDef.Description = "A description for this build defintion";
buildDef.ContinuousIntegrationType = ContinuousIntegrationType.Individual; //CI

//Controller and default build process template
buildDef.BuildController = buildServer.GetBuildController("Hosted Build Controller");
var defaultTemplate = buildServer.QueryProcessTemplates(tp).First(p => p.TemplateType == ProcessTemplateType.Default);
buildDef.Process = defaultTemplate;

//Drop location
buildDef.DefaultDropLocation = "#/";    //set to server drop

//Source Settings
buildDef.Workspace.AddMapping("$/Path/project.sln", "$(SourceDir)", WorkspaceMappingType.Map);
buildDef.Workspace.AddMapping("$/OtherPath/", "", WorkspaceMappingType.Cloak); 

//Process params
var process = WorkflowHelpers.DeserializeProcessParameters(buildDef.ProcessParameters);

//What to build
process.Add("ProjectsToBuild", new[]{"Test.sln"});
process.Add("ConfigurationsToBuild", new[]{"Mixed Platforms|Debug"});

//Advanced build settings
var buildParams = new Dictionary<string, string>();
buildParams.Add("PreActionScriptPath", "/prebuild.ps1");
buildParams.Add("PostActionScriptPath", "/postbuild.ps1");
var param = new BuildParameter(buildParams);
process.Add("AdvancedBuildSettings", param);

//test settings
var testParams = new Dictionary<string, object>
                                 {
                                     { "AssemblyFileSpec", "*.exe" },
                                     { "HasRunSettingsFile", true },
                                     { "ExecutionPlatform", "X86" },
                                     { "FailBuildOnFailure", true },
                                     { "RunName", "MyTestRunName" },
                                     { "HasTestCaseFilter", false },
                                     { "TestCaseFilter", null }
                                 };

var runSettingsForTestRun = new Dictionary<string, object>
                                            {
                                                { "HasRunSettingsFile", true },
                                                { "ServerRunSettingsFile", "" },
                                                { "TypeRunSettings", "CodeCoverageEnabled" }
                                            };
testParams.Add("RunSettingsForTestRun", runSettingsForTestRun);

process.Add("AutomatedTests", new[]{ new BuildParameter(testParams)});
            
//Symbol settings
process.Add("SymbolStorePath", @"\serversymbolssomepath");

buildDef.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(process);

//Retention policy
buildDef.RetentionPolicyList.Clear();
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Succeeded, 10, DeleteOptions.All);
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Failed, 10, DeleteOptions.All);
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Stopped, 1, DeleteOptions.All);
buildDef.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.PartiallySucceeded, 10, DeleteOptions.All);

//Lets save it
buildDef.Save();

 

Hope you find this useful!

Getting started with InRelease and TFS 2013 Preview

As you probably already know, Microsoft recently acquired InRelease, a release management product build by InCycle software that integrates tightly with Team Foundation Server. This acquisition fills a huge gap in the Visual Studio ALM suite, letting customers handle the release management and automatic deployment of their solution. This is a crucial feature for enabling Continuous Deployment.

In this post I will show you how to get started with using InRelease, by installing it and setting up your first release including automatic deployment to a staging server. I expect to blog some more about InRelease in the near future, looking at the nitty gritty details of release automation and deployment using InRelease.

Note: Both TFS 2013 and this edition of InRelease are still in preview and details can change in time for the RTM version.

InRelease Overview

A deployment of InRelease typically looks like this:

image

 

So we have three main components here:

  • InRelease Server
    The server consists of both a windows and a web service that the deployers and clients communicates with (using HTTP/HTTPS). 
  • InRelease Deployer
    The Deployer is a windows service that is installed on each target server where you want to deploy your applications. Like Visual Studio Lab Management, you can define environments that consist of several servers (physical or virtual). But each servers needs to have a deployer agent installed to be able to carry out the actual deployment.
  • InRelease Client
    There are in fact two clients. There is a WPF application that is the main interface for managing all release information. In addition there is a web application where users can act on approval requests, that is sent out using email.

InRelease Concepts

There are several concepts in InRelease that you need to understand in order to fully utilize it. These concepts are related to each other as well, and it can be a bit tricky in the beginning to understand how they relate to each other.

  • Stage Type
    This corresponds to a set of logical steps that are required to move your application build from development all the way to production. Typically you will have stages for Development, QA, User Acceptance Test, Production etc.
  • Technology Type
    These are basically tags that allow you to specify what kind of technologies that are used on your target servers and environments. These tags are used by InRelease for anything, they are merely informational values.
  • Environment
    As mentioned above, an environment consist of one or more servers.  
  • Server
    In order to deploy your application, you need to register your target servers in InRelease. Add the servers using the DNS name and InRelease will register the IP address of the server that first time the Deployer agent on that machine communicates with the Server.
  • Release Path
    A Release Path is how you distribute a release in a certain scenario. Even though you will often use the same release path every time for your application, you might for example define one release path for major releases and another release path for minor/hotfix releases, since these might have different pre- or post validation steps.
  • Release Template
    A Release Template is the workflow that is used for releasing an application. Users that are familiar with TFS Build will find themselves at home here, since InRelease also uses Windows Workflow for create the deployment orchestration, by using a sequence predefined Workflow Activities.
  • Release
    Defines a specific release of an application or system. A release is defined by associating it with a Release Template, a Stage Type and a Build. You want to use TFS Build here and associate the Release Template with a corresponding TFS Build, but it is also possible to use a UNC path as the source of deployment items, in case you for example use Team City as your build automation tool.
  • Tool
    Represents an executable piece of code, for example a PowerShell or a batch file, or an executable. The only real important thing here is that it is possible to execute the tool silently from command line. A tool is always used by either an Action or a Component
  • Action
    An object in InRelease that can be used in a deployment sequence. Often this is a tool with the corresponding command and parameters, such as MSI Deployer or Windows Process.
  • Component
    Part of an application that needs to be installed. For example a database, web site or  a windows service. A component has a source, which often is fetched from the TFS Build drop folder

 

Installing InRelease

The installation procedure is pretty straight forward except some minor issues that should be improved by RTM. Martin Hinshelwood has posted some of these issues herehere and here.

The InRelease Server uses SQL Server to store all its information, this can be basically any version, and can be hosted remotely. In addition, the InRelease server has the following prerequirements, so make sure that you install/enabled these features before:

image_thumb[9]

Note that it is possible to run on IIS 6 as well, check the installation manual

After you have installed everything, you first need to add users. Start the InRelease Client and go to Administration –> Users:

SNAGHTML1f1578f9_thumb[1]

Select the windows account by browsing your AD directory. This will automatically fill out the name and email address for you, as long as this information is available in AD.
Also mark if the user is a Release Manager and/or a Service User. Release Managers have access to everything, and Service Users are used for deployer accounts and TFS build service account.
These users won’t show up in any lists where you select users.

SNAGHTML1f1915f3_thumb[1]

 

Next up, you need to register the connection to TFS. Enter the name of your TFS server, and the credentials that should be used for accessing it.

SNAGHTML2013a2ad

Verify that the TFS connection works properly, after this you should be good to go and start creating releases!

 

Creating and deploying a Release

Lest walk through how to get started quickly, by creating a new release and deployment sequence for an application. In this case, I am reusing our existing release build for this application, but will manage and deploy it using InRelease. This build already produces an MSI (using Wix) so we will use an existing InRelease tool called MSI Deployer, that is capable of executing a MSI with custom parameters as part of the deployment.

These are the steps that we will walk through:

  1. Define the Stage Types
  2. Create an Environment for the test server
  3. Register the test server
  4. Create a Release Path for our release
  5. Setup a component that installs our MSI
  6. Create a Release Template that uses the component
  7. Create a Release

Define the Stage Types

We will setup to stage types here, one for Test and one for Production. Go to Administration –> Pick List and select Stage Types. Create two Stage Types, called Test and Production:

SNAGHTML1f7a177b

Define the staging server in InRelease

Now we will register our existing test server used for staging the application. This is the server where we have installed the InRelease Deployer agent, which is used for running the deployment sequence on that machine. Note that a release can of course reference many servers, and each server has its own steps in the deployment sequence.

SNAGHTML1f86c797

Here I have registered the customer test server, running on our lab network. I have assigned myself as the owner of this server, and added a short description. In addition I have used the default option of how the InRelease Deployer should access the build drop location, namely directly through the UNC path. If this is a problem, which it can be due to security restrictions, you can use the other option in which the InRelease Server accesses the drop location and the InRelease Deployer agents gets the files from the IR Server using HTTP(S). This is slower, especially if you have large files.

Note the error that is shown. This means that the InRelease Deployer on the server have not yet communicated with the server. As soon as it does, the error will disappear and the IP Address will be filled out.

Create an Environment for the test servers

We also need to create environments for each stage type. In this case, each environment will only consist of one server, but often you will have several servers, such as web servers, database server, application servers and so on.

SNAGHTML1fe9abd0

Here I have created a Test environment that includes the test server. I will also create a Production environment for the production server(s).

Create a Release Path for our release

Now lets define how the release should flow through the different stages. We will define how each stage should be handled, if the deployment is automatic or not, and if the different steps should be validated and approved by someone.

SNAGHTML1f92e323

 

As you can see I have added both stages here, but the different steps are a bit different for each step. On the test server I want to automate the acceptance and validation step, and I will approve the deployment afterwards myself. In the production environment, the release first have to be accepted (by my colleague Terje in this case Ler ) before the deployment proceeds. Also, Terje will be validating and approving the release in the production environment.

Setup a component that installs our MSI

Before create the release template, we need to create a component that will install our MSI. As mentioned before, components can be reused in multiple release template, by using arguments. So first we give the component a name and then point to where the package that belongs this component can be retrieved:

SNAGHTML1fa8b012

In my case, all the MSI’s from the TFS build is located at the drop folder root. In this case, I must add a ‘’ in the Build Drop Location to have InRelease understand that.

Note the the build definition will be defined in the Release Template. We could also choose to select an independent build, basically any build that has already been executed. We could also point to a UNC share, which would allow us to use InRelease without TFS Build, for example is you use TeamCity.

Next we select the Deployment tab, in which we specify how this component is actually installed. Here we can select from a list of predefined tools, in this case we select the MSI Deployer tool. Each tool has its own set of commands, arguments and parameters. A sample argument will be created when selecting the tool, so all you need to do is to change the parameter values to match your packages.

image

The MSI Deployer tool, like many other InRelease tools, uses Powershell as implementation.
Here I have referenced my installer and added the specific MSI argument that is needed in order to deploy it on the test server, such as web site name, port, app pool and install directory.

 

Create a Release Template that uses the component

Now lets create a Release Template that utilizes this component. Go to Configure Apps –> Release Template and create a new template. Fill out a name and description, and select the Release Path that we just created. Also, we can select which build definition that belongs to this release template. This is where the component will fetch its packages from, and it also allows us to later on automatically trigger a release from a build, as I will show in a later post.

SNAGHTML1fb789be

 

Next up we define the Deployment sequence for each stage of the corresponding Release Path, which in our case is Test and Production. You will that in addition to the existing predefined tools the servers and components that you have defined show up in the toolbox.

SNAGHTML1fbae7f4

Here I have first dragged the server onto the workflow surface, and then added the Customer Web Site MSI installer inside the Server activity. This signals that the component shall be executed on that server. I could very well have multiple servers here, and tools/components are always placed within a server node.

Of course there are a lot more things that you can do here, there are tools for creating and configuring web sites, SQL databases, Windows Services and starting and stopping Azure VMs. In my case, I already had an MSI from before, so all I need to do here is to make sure that it is executed with the correct parameters.

 

Create a Release

Finally, it is time to actually release something Ler 

By selecting the Release Template, we can click on New Release to create a new Release for this release path. Here we select which Target Stage that we should release to, and which build that should be deployed.

SNAGHTML1fc62ca2

 

Here I have clicked on Latest, which automatically finds the latest build for my associated build definition, but it is also possible to select a previous build.

Now I can select Create in Draft which allows me to postpone the release for later, or I can be bold and click in Start immediately.

SNAGHTML1fca5beb

Here we can see that the Release is in progress, and the first three steps are already done. Remember that we set the Accept Deployment step and the Validate Deployment step to automatic for the Test stage. The Deploy step has executed in about 3 seconds, and we can view the log by clicking the button in the Details column.

Finally, the release has stopped in the Approve Release step. This step is manual, and is waiting for me to approve the release. To make this workflow happen, I have received the following email from the InRelease Server:

 

image

 

After I have surface tested the deployment and verified if it meets the quality gates defined for the release or not, I can click the View Request link which will redirect me to the InRelease web application where I can select to Approve or Reject the release.

 

Conclusion

This post has shown how you quickly can get started with InRelease and TFS 2013. As mentioned before, this is still prerelease software, so there are still some know bugs in the software.

New Book: Pro Team Foundation Service

The last couple of months I have been working together with Mathias Olausson, Mattias Sköld and Joachim Rossberg on a new book project for Apress that has just been published. The book is called Pro Team Foundation Service and covers all aspects of working with Team Foundation Service, Microsoft’s hosted version of Team Foundation Server in the cloud. I have mainly worked on the chapter related to automated build and continuous deployment, but also with some of the other chapters.

It has been a quite hectic  project due to a tight schedule, but at the same time it has been a lot of fun to work on this book together with late night meetings and weekends filled with book writing and chapter editing.

During the project we’ve had great help from several people at Microsoft, Jamie Cool, Will Smythe, Anutthara Bharadwaj, Ed Blankenship and Vijay Machiraju. Also a big thanks to Brian Harry for writing the foreword to the book. In addition I’d like to thank my colleague Terje Sandstrøm for helping out with Technical Review of large parts of the book.

Here is some information about the book, you can find it on Amazon here:
http://www.amazon.com/Team-Foundation-Service-Mathias-Olausson/dp/1430259957#_

Check it out and let us know what you think!

clip_image001

Pro Team Foundation Service gives you a jump-start into Microsoft’s cloud-based ALM platform, taking you through the different stages of software development. Every project needs to plan, develop, test and release software and with agile practices often at a higher pace than ever before.
Microsoft’s Team Foundation Service is a cloud-based platform that gives you tools for agile planning and work tracking. It has a code repository that can be used not only from Visual Studio but from Java platforms and Mac OS X. The testing tools allow testers to start testing at the same time as developers start developing. The book also covers how to set up automated practices such as build, deploy and test workflows.

This book:

· Takes you through the major stages in a software development project.

· Gives practical development guidance for the whole team.

· Enables you to quickly get started with modern development practices.

With Microsoft Team Foundation Service comes a collaboration platform that gives you and your team the tools to better perform your tasks in a fully integrated way.


What you’ll learn

· What ALM is and what it can do for you.

· Leverage a cloud-based ALM platform for quick improvements in your development process.

· Improve your agile development process using integrated tools and practices.

· Develop automated build, deployment and testing processes.

· Integrate different development tools with one collaboration platform.

· Get started with ALM best-practices first time round.


Who this book is for

Pro Team Foundation Service is for any development team that wants to take their development practices to the next level. Microsoft Team Foundation Service is an excellent platform for managing the entire application development lifecycle and being a cloud-based offering it is very easy to get started. Pro Team Foundation Service is a great guide for anyone in a team who wants to get started with the service and wants to get expert guidance to do it right.


Table of Contents

1. Introduction to Application Lifecycle Management

2. Introduction to Agile Planning, Development, and Testing

3. Deciding on a Hosted Service

4. Getting Started

5. Working with the Initial Product Backlog

6. Managing Team and Alerts

7. Initial Sprint Planning

8. Running the Sprint 

9. Kanban

10. Engaging the Customer

11. Choosing Source Control Options

12. Working with Team Foundation Version Control in Visual Studio

13. Working with Git in Visual Studio

14. Working in Heterogeneous Environments

15. Configuring Build Services

16. Working with Builds

17. Customizing Builds

18. Continuous Deployment

19. Agile Testing

20. Test Management

21. Lab Management

Extending Team Explorer 2012 – Associating Recent Work Items

Extension available at: http://visualstudiogallery.msdn.microsoft.com/9ed2d30c-a692-42b0-a21d-cdc8d2bf322c

 

I have been playing around a bit lately with extending Team Explorer 2012, mostly because it is fun but also to fix a little nagging feature that should have been there from the beginning. Often I (and a lot of other people) find myself wanting to associate several consecutive changesets to the same work item. The problem is that Team Explorer does not remember this, instead I have to either remember the ID or use a query that hopefully will match the work item.

image 
Where is the work item that I just associated with?
 
True, when using the My Work page and the teams and sprint backlogs are correctly setup, you can find “your” work items there, but every so often this is not the case, and off I go to locate that work item again.

So this seemed to be a good feature to implement and at the same time learn a little about how to extend Team Explorer in Visual Studio 2012.

There is a great sample posted by Microsoft over at MSDN, it also talks about the main extension points and classes/interfaces that you need to know about. You can find it here: http://code.msdn.microsoft.com/windowsdesktop/Extending-Explorer-in-9dccd594. If you have developed extensions to Visual Studio before, you will be relieved to know that this new extension model for Team Explorer is purely based on standard .NET/WPF and MEF, no weird COM interfaces.

You can add new pages to Team Explorer, you can add new sections to existing pages and you can add navigation links to the Home screen. All these extensions are discovered by Team Explorer using the Managed Extensibility Framework (MEF). You just need to attribute your classes with the correct attribute and it will be found by Team Explorer. The attributes also control where your extension will appear. This extension is a Section that should appear inside the Pending Changes page:

 image
Example of attributing a Team Explorer extension

The last property (35) is a priority number that controls when the extension is created and also where it will placed relative to the other sections. The existing Related Work Items section has priority 30, so 35 will place our extension right below it.

We also need to implement the ITeamExplorerSection interface, that contains properties and methods that needs to be implemented for anything to show up.

image
ITeamExplorerSection interface

The most interesting property here  is the SectionContent property which is where you return the content of your extensions. This is typically a WPF user control in which you can add any controls you like. 

This is how the extension appear inside the Pending Changes page. It will analyze your recent changesets in the current team project and extract the last 5 associated work items and show them in a list.
From the list you can then easily add a work item to the current pending changes by right-clicking on it and select Add. You’ll note that the work item will then disappear from the list, since you are not likely interested in adding it again.

image

Recently Associated Work Item section

I encourage you to read the MSDN article for more information about the possibilities to extend Team Explorer 2012. Also, try out the extension and let me know it you find it useful!

TFS Build: Running Static Code Analysis for Specific Configuration

Running Static Code Analysis (SCA) is something that you should be doing regularly to verify your code base against a large set of rules that will check your code for potential problems and how it comply with standard patterns such as naming conventions for example. Microsoft include several different rule sets that you can use for starters, but you can build your own rule sets as well, that contain the rule that you want to use, In addition, you can write your own custom rules and add these to your rule sets.

What you will notice quickly when you start running SCA for larger solutions is that it can take a lot of time. Therefore, you normally don’t want to run this on your local build but instead run it as part of your automated builds. It is recommended to set up a specific build for your projects that measures code quality, by running for example SCA, Code Metrics and Code Coverage. All these things take time to complete, so don’t put these in your Check-In builds, but in a Quality Assurance (QA) build.


Configuring Static Code Analysis

With Team Foundation Build, it is easy to run Static Code Analysis as part of the build, just modify the Perform Code Analysis process parameter in your build definition:

image

 

There are three possible values that you can use here:

  • Never – Never run Static Code Analysis
  • As Configured – If the project is configured to run Static Code Analysis for the current configuration, then SCA will be executed
  • Always – Always run Static Code Analysis, independent of how the projects are configured

If you select As Configured, you need to make sure that you have configured your projects correctly. This is done by opening the Properties window for your project and select the Code Analysis tab:

image 

As you can see, the Code Analysis settings are specific to the Configuration and Platform for the project. This means that you can, for example, run code analysis only on Debug builds and not on Release builds.

Now, while using project specific settings like this to control when SCA is executed works, it has some drawbacks. When the solutions start to grow in size, it can be hard to make sure that the settings in every project is correctly configured. Also, as mentioned before, you typically don’t want to run SCA at all on your local builds, since it makes your build times longer. This can be solved by for example making sure that only the Release configuration has the Enable Code Analysis on Build property set to true, and then you only build the Debug configuration locally.

A better way to solve this is to control this completely from the build definition instead. You do this by setting the Perform Code Analysis process parameter to Always, as shown above. This will make sure that SCA are run for all projects, no matter how they are configured.

Running SCA for specific configurations

A problem that we faced recently at a customer that are running big builds (1+ hours) is that they are building both the and Debug and Release configurations as part of their builds. We wanted to run SCA on these builds, and we don’t want to configure each project (the solutions has 150+ projects in it). But, setting Perform Code Analysis to Always, this will result in SCA being run for both Debug and Release builds resulting in a considerable increase in build time.

So, how can we make sure that SCA is executed on all projects, but only on on (or several) configurations? One way of doing this is to customize your build template and add a parameter that specifies these configurations.

Here are the steps to accomplish this:

  1. If creating a new build template from scratch, branch the DefaultTemplate.11.1.xaml build process template.
  2. Open the template in Visual Studio
  3. Select the top Sequence activity and expand the Arguments tab
  4. At the bottom of the list, add a new parameter called RunSCAForTheseConfigurations with StringList as type

      image

  5. Locate the MetaData process parameter and click on the browse button on the very right
  6. Add a new entry for the new parameter

    image

  7. Inside the workflow, locate the MSBuild activity that is used for compiling the projects. It is right at the end of the Compile the Project sequence:

    image

  8. Right-click the MSBuild activity and select Properties

  9. Locate the RunCodeAnalysis property and open the expression editor

  10. Enter the following expression

    image 

    The expression evaluates if the current configuration (platformConfiguration.Configuration) is specified in our new property.

  11. Save the workflow and check it in

Now you can create a new build definition and enter one or more configurations in the new property:

 

Since this is a property of type StringList, you can add multiple configurations here if you want to.

You can see from this build summary that SCA has only been performed on the Debug configuration, and not for Release.

image

 

Conclusion

I have shown one way to implement automatically running Static Code Analysis on a subset of configurations for a build that builds multiple solutions. This is very useful when you have large builds that compile multiple configurations.

Hope you found this post useful.

Book “Team Foundation Server 2012 Starter” published!

During the summer and fall this year, me and my colleague Terje Sandstrøm has worked together on a book project that has now finally hit the stores!
The title of the book is Team Foundation Server 2012 Starter and is published by Packt Publishing.

You can find it at http://www.packtpub.com/team-foundation-server-2012-starter/book or from Amazon http://www.amazon.com/dp/1849688389 

                      image 

The book is part of a concept that Packt have with starter-books, intended for people new to Team Foundation Server 2012 and who want a quick guideline to get it up and working. It covers the fundamentals, from installing and configuring it, and how to use it with source control, work items and builds. It is done as a step-by-step guide, but also includes best practices advice in the different areas. It covers the use of both the on-premises and the TFS Services version. It also has a list of links and references in the end to the most relevant Visual Studio 2012 ALM sites.

Our good friend and fellow ALM MVP Mathias Olausson have done the review of the book, thanks again Mathias!

We hope the book fills the gap between the different online guide sites and the more advanced books that are out. Check it out and please let us know what
you think of the book!

Book Description

Your quick start guide to TFS 2012, top features, and best practices with hands on examples


Overview

  • Install TFS 2012 from scratch
  • Get up and running with your first project
  • Streamline release cycles for maximum productivity


In Detail

Team Foundation Server 2012 is Microsoft’s leading ALM tool, integrating source control, work item and process handling, build automation, and testing.

This practical “Team Foundation Server 2012 Starter Guide” will provide you with clear step-by-step exercises covering all major aspects of the product.
This is essential reading for anyone wishing to set up, organize, and use TFS server.

This hands-on guide looks at the top features in Team Foundation Server 2012, starting with a quick installation guide and then moving into using it for your
software development projects. Manage your team projects with Team Explorer, one of the many new features for 2012.

Covering all the main features in source control to help you work more efficiently, including tools for branching and merging, we will delve into the Agile Planning
Tools for planning your product and sprint backlogs.

Learn to set up build automation, allowing your team to become faster, more streamlined, and ultimately more productive with this
“Team Foundation Server 2012 Starter Guide”.


What you will learn from this book

  • Install TFS 2012 on premise
  • Access TFS Services in the cloud
  • Quickly get started with a new project with product backlogs, source control, and build automation
  • Work efficiently with source control using the top features
  • Understand how the tools for branching and merging in TFS 2012 help you isolate work and teams
  • Learn about the existing process templates, such as Visual Studio Scrum 2.0
  • Manage your product and sprint backlogs using the Agile planning tools


Approach

This Starter guide is a short, sharp introduction to Team Foundation Server 2012, covering everything you need to get up and running.


Who this book is written for

If you are a developer, project lead, tester, or IT administrator working with Team Foundation Server 2012 this guide will get you up to speed quickly
and with minimal effort.