Deploy On Premise Builds with Visual Studio Release Management vNext

Microsoft’s new version of Visual Studio Release Management is currently in public preview in VSTS. It is currently targeted for the TFS 2015 Update 2 version that should be shipped later this spring.

However, even if you are not all in on Visual Studio Team Services, you can still use this service! Since the build/release agents that are used can run on premise without any necessary firewall ports being opened inbound, you have full access to any internal TFS servers and application servers that you want to deploy to.

 

The following image illustrates the different components involved here.

 image

 

As you can see everything is running on premise, except Visual Studio Team Services of course. Since the release agent is also running on premise, it can connect to the on premise TFS and download the build artifacts, and it can access the on premise application servers and deploy the artifacts.

 

Lets’s walk through how you can use Visual Studio Release Management today to deploy builds from your on premise TFS build server to an on premise web server.

Creating the Release Definition

  1. I’m not going to walk through how to create a build definition in TFS, there are plenty of documentation on that. Let’s just look at the artifacts of the build that we will deploy:

    image 

  2. Nothing special here, this is the standard output from a build that runs msdeploy to create web deploy packages.
  3. Now, to be able to consume the build artifacts from a release definition, we need to setup a service endpoint for the TFS server. In the new build and release management system, service endpoints are a fundamental concept. They encapsulate the information, including credentials, that is needed to integrate with an external system. Example of service endpoints include Azure subscriptions, Jenkins build servers and Chef servers. In addition we can create Generic service endpoints, which contains a server URL and a user name and a password. This is what we will use here.
  4. Service endpoints also have there own security groups, which means that we can for example make sure that only certain people can use a service endpoint that points to the production Azure subscription

    Service points are scoped to the team project level, and are available on a separate tab on the admin page. In this case, we will create a Team Build endpoint, where we supply the URL of the TFS server and the necessary credentials for it:

    image

  5. With the service endpoint done, we can move on to create a release definition. In this example, I will define two environments, Dev and Prod that will just point to two different web sites on the same server.

     image

    As you can see, I only have two tasks in each environment. The first task is a custom task that replaces any tokens found in the files that matches the supplied pattern.. This lets me apply environment specific values during the build. In this case, I will update the *.SetParameter.xml file that is used together with web deploy.

    Also, I use the configuration functionality to supply the machine name of the web server and the name of the web site that I will deploy this to. As you can see below, I will deploy both dev and production to the same server, but to different web sites. Not entirely realistic, but you should get the idea here. You can see that I use the variable $(webSite) in the task above, where I run the generated web deploy command file.

    image

  6. Now, the part that is different here compared to a standard release definition is the linking of artifacts. Here we will select “Team Build (external)”, which in this context mean any TFS server that is defined as a service endpoint. In the Service dropdown we select the service endpoint that we created earlier (TFS).We also need to supply the name of the team project and the name of the build definition, as shown below.

    image


    1. NOTE
      : When linking to an external build like this, we do it by name. This means that if you change the name of the build definition or the team project, you will have to change this artifact definition.
  7. Now we can save the release definition and start a release. A big difference compared to when you have linked to a VSTS build is that RM won’t locate the existing builds for you, so you have to supply the build number yourself of the build that you want to release.
  8. image
  9. When the release has finished we can see that the selected build version (1.0.0.6) has been deployed to both environments:
  10. image

 

Summary

As you can see, there is nothing that stops you from start using the new version of Visual Studio Release Management, even if you have everything else on premise.

Managing Build Templates with Community TFS Build Manager

A year ago I blogged about how to manage your build process templates using the TFS API. The main reason for doing this is that you can (and should!) store your “golden” build process templates in a common location in your TFS project collection, and then add them to each team project that requires those templates. This way, you can fix a bug or add a new feature in one place and have the change affect all build definitions.

However, by having the build process templates in a single location, the users must know where the build process templates are located and browse to that path and add it to the team project, before it will show up in the list of build process templates:

image

Unfortunately, you can’t manage the build process templates this way using Team Explorer, you have to resort to the TFS API to do these things.

Until now! Ler In the latest release of the Community TFS Build Manager I have added support for managing build process templates.

The templates are accessible by selecting “Build Process Templates” in the “Show” dropdown:

image

This will show all registered build process templates, either in the selected team project or in all team projects, depending on your current filter:

image

All build process templates in the XDemo team project. The grid is of course sortable as the rest of the application. This lets you easily see where the template is registered.

Note that several of the build process templates in the list above is stored in the Inmeta team project, which is our team project for storing all artifacts related to our software factory, including the build process templates and custom activities.

Now, we can right click on a build process template and perform any of the following actions:

image

 

  • Set As Default
    This will set the selected build process template as the default build process template in the corresponding team project. There can only be one default build process template per team project, so the tool will automatically scan for any other default build process templates and set them back to “Custom”. 
  • Add to Team Project(s)
    This will let you select one or more team projects where you want to add this build process template to:

    image

    In the list you can select one or more team projects. You can also specify that the template(s) should be set as default by using the checkbox “Set as Default”.

  • Remove from Team Project(s)
    This does the opposite from the previous operation, it removes the selected build process template(s) from one or more team project. After this operation, the template will not be visible in the “Build Process file” dropdown when editing a build process template.

    Note: When removing a build process template, there might be build definitions using this template. If this is the case, the build manager will prompt you with a dialog before you proceed with the remove:

    image

Hope that you find the new functionality useful. Please report bugs and feature requests to the Community TFS Build Extensions CodePlex site

Handling Warnings and Errors with InvokeProcess in TFS 2010 Build

The InvokeProcess activity is very useful when it comes to running shell commands and external command line tools during a build process. When it comes to integrating with TFS source control during a build, the TF.exe command line tool can be your friend, as it lets you do most of the usual stuff such as check-in, checkout, add, modify workspaces etc.

However, it can be a bit tricky to handle the output from tf.exe, since it often produces warnings that is not necessarily a problem for your build. This is not a problem related only to tf.exe, but to all applications that produces errors and warnings on the canonical error format.

The normal way to use the InvokeProcess activity is to setup the necessary parameters to call the tool with the correct path, working directory and command line switches. Then you add a WriteBuildMessage activity to the Handle Standard Output action handler and a WriteBuildError to the Handle Error Output action handler. In addition, you store the Result output property from the InvokeProcess activity in a workflow variable that you can evaluate after the InvokeProcess activity has finished.

image

 

This will output all standard output from the application to the build log, and all errors will be written as errors to the build log and will partially fail the build.
If you try this with TF.exe you will probably notice a problem with warnings from the tool being reported as errors in the build, causing it to partially fail the build, even though the ReturnCode was zero.

To solve this problem you need to collect the information that is passed to the Error Output action handler. Note that this handler is called several times so you need to handle formatting of the output in some way. Then, you check the ReturnCode from the InvokeProcess activity and in case this is <> 0, you write the collection information as an error to the build log (using WriteBuildError) and then throw an exception. Otherwise, just write the information to the build log using WriteBuildMessage, so you get all information out there.

The finished sample looks like this:

image

In the “Check out files” sequence I have defined a workflow variable called ErrorOutputFromTF of type string. In the “Handle Error Output” handler, I append the error to this variable, using the Assign activity:

image

I just append a newline character at the end to have all the errors on separate rows in the build log later. After the InvokeProcess activity I check the TFExitCode variable,  that was assigned the ResultCode value from the InvokeProcess activity previously, if it is <> 0 I write the ErrorOutputFromTF to the build error log and then I throw an exception.

Here is a sample build log output:

image

Note that tf.exe in this case outputs information about check-in policies that have been overridden. This is an example of information that would cause the build to partially fail, but is now logged as information.

Avoiding TF237124 when Creating Work Items in New Areas

At my company we write a lot of tools and extensions that uses the TFS API to automate various things for us. A very common thing to automate is the creation of work items and the areas and iterations structure.

Creating a work item using the TFS API is simple, just connect to TFS, get the WorkItemStore service object and create a new work item and set any fields that you want to:


Creating a work item

//Connect to TFS and get the WorkItemStore object var tfs = new TfsTeamProjectCollection(new Uri("http://localhost:8080/tfs")); var wis = tfs.GetService(typeof(WorkItemStore)) as WorkItemStore; //Get team project var teamProject = wis.Projects["Demo"]; //Get the Bug Work Item Type var wit = teamProject.WorkItemTypes["Bug"]; //Create a new Bug work item and set the title field WorkItem wi = new WorkItem(wit); wi.Title = "New Bug In New Area"; wi.Save();

 

Creating an area or iteration is equally simple:



Creating an area

//Connect to TFS and get the ICommonStructureService object var tfs = new TfsTeamProjectCollection(new Uri("http://localhost:8080/tfs")); var css = tfs.GetService(typeof(ICommonStructureService)) as ICommonStructureService; //Get the root path of the new area string rootNodePath = "\Demo\Area"; var pathRoot = css.GetNodeFromPath(rootNodePath); //Create the new area, in this case it will be a new root area css.CreateNode("NewRootArea", pathRoot.Uri);

 

BUT (yes there is a but, you could sense it coming), when you combine these two fellows into one task, e.g. create a new area (or iteration) and then create a new work item in that area, chances are high that you will receive the following exception:

Microsoft.TeamFoundation.WorkItemTracking.Client.ValidationException: TF237124: Work Item is not ready to save

   at Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem.Save(SaveFlags saveFlags)

   at Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem.Save()


The meaning of the error is not obvious, but if you would call the Validate() method before calling Save() (which you should, of course) you would see that it returns the Area field indicating that this field is the problem.

The underlying problem here is that in the TFS Data Store, work items and areas/iterations are persisted in two different stores. And these stores need to be synchronized before you can reference any new items that you added. You’ll notice the same issue in Visual Studio as well, when you create a new area or iteration in Team Explorer, you need to refresh Team Explorer in order to use the new nodes for work items.

But how do we do this programmatically? There actually two things that needs to be done:

  1. Request that the work item store is synchronized with the Common Structure store
  2. Refresh the local cache

Which is translated into the following code



Synchronize External Stores

//Synchronize the work item store with external stores (e.g. CSS) private static void SyncExternalStructures(TfsTeamProjectCollection tfs, WorkItemStore wis, ICommonStructureService css, string teamProject) { //Get work item server proxy object WorkItemServer witProxy = (WorkItemServer)tfs.GetService(typeof(WorkItemServer)); //Get the team project ProjectInfo projInfo = css.GetProjectFromName(teamProject); //Sync External Store witProxy.SyncExternalStructures(WorkItemServer.NewRequestId(), projInfo.Uri); //Refresh local cache wis.RefreshCache(); }

 

Call this method after creating the area/iterations and before creating the new work item and it will work as expected

Introducing: Community TFS Build Manager

The latest release of the Community TFS Build Extensions include a brand new tool called Community TFS Build Manager and has been created for two reasons:

  1. An implementation of the Team Foundation Build API which is referenced by the Rangers Build Customization Guidance V2 (available H1 2012)
  2. Provide a solution to a real problem. The Community TFS Build Manager is intended to ease the management of builds in medium to large Team Foundation Server environments, though it does provide a few features which all users may find useful.

The first version of the tool has been implemented by myself and Mike Fourie. You can download the extension from the Visual Studio Gallery here:
http://visualstudiogallery.msdn.microsoft.com/16bafc63-0f20-4cc3-8b67-4e25d150102c


Note 1:
The full source is available at the Community TFS Build Extension site

Note 2: The tool is still considered alpha, so you should be a bit careful when running commands that modify or delete information in live environments, e.g. try it out first in a non-critical environment.

Note 3: The tool is also available as a stand alone WPF application. To use it, you need to download the source from the CodePlex site and build it.

 

Getting Started

You can either install the extension from the above link, or just open the Visual Studio Extension Manager and go to the Online gallery and search for TFS Build:

image

 

After installing the build manager, you can start it either from the Tools menu or from the Team Explorer by right-clicking on the Builds node on any team project:

 

image

This will bring up a new tool window that will by default show all build definition in the currently selected team project.


View and sort Builds and Build Definitions across multiple Build Controllers and Team Projects
This has always been a major limitation when working with builds in Team Explorer, they are always scoped to a team project. It is particularly annoying when viewing queued builds and you
have no idea what other builds are running on the same controller. In the TFS Build Manager, you can filter on one/all build controllers and one/all team projects:

image

 

The same filters apply when you switch between Build Definitions and Builds. In the following screen shot, you can see that three builds from three different team projects are running on the same controller:

image

You can easily filter on specific team projects and/or build controllers. Note that all columns are sortable, just click on the header column to sort it ascending or descending.
This makes it easy to for example locate all build definitions that use a particular build process template, or group builds by team project etc.

 

Bulk operations on Build Definitions

The main functionality that this tool brings in addition to what Team Explorer already offers, is the ability to perform bulk operations on multiple build definitions/builds. Often you need to modify or
delete several build definitions in TFS and there is no way to do this in Team Explorer.

 

In the TFS Build Manager, just select one or more builds or build definitions in the grid and right-click. The following context menu will be shown for build definitions:

image

 

Change Build Process Templates

This command lets you change the build process template for one or more build definitions. It will show a dialog with all existing build process templates in the corresponding team projects:

image

 

Queue

This will queue a “default” build for the the selected build definitions. This means that they will be queued with the default parameters.

 

Enable/Disable

Enables or disables the selected build definitions. Note that disabled build definitions are by default now shown. To view disabled build definitions, check the Include Disabled Builds checkbox:

 

image

 

Delete

This lets you delete one ore more build definitions in a single click. In Team Explorer this is not possible, you must first delete all builds and then delete the build definition. Annoying! Ler

TFS Build Manager will prompt you with the same delete options as in Team Explorer, so no functionality is lost:

image

 

Set Retention Policies

Allows you to set retentions policies to several build definitions in one go. Note that only retention policies for Triggered and Manual build definitions can be updated, not private builds. 
This feature also gives you the same options as in Team Explorer:

image

 

Clone to Branch

My favorite feature Ler Often the reason for cloning a build definition is that you have created a new source code branch and now you want to setup a matching set of builds for the new branch. When using the Clone build definition feature of the TFS Power Tools, you must update several of the parameters of the build definition after, including:

  • Name
  • Workspace mappings
  • Source control path to Items to builds (solutions and/or projects)
  • Source control path to test settings file
  • Drop location
  • Source control path to TFSBuild.proj for UpgradeTemplate builds

All this is done automagically when using the Clone to Branch feature! When you select this command, the build manager will look at the Items to build path (e.g. solution/projects) and find all child branches to this path and display them in a dialog:

image

When select one of the target branches, the new name will default to the source build definition with the target branch name appended. Of course you can modify the name in the dialog. After pressing OK, a new build definition will be created and all the parameters listed above will be modified accordingly to the new branch.

 

Bulk operations on Builds

You can also perform several actions on builds, and more will be added shortly. In the first release, the following features are available:

 

Delete

This will delete all artifacts of the build (details, drops, test results etc..). It should show the same dialog as the Delete Build Definition command, but currently it will delete everything.

Open Drop Folders

Allows you to open the drop folder for one or more builds

 

Retain Indefinitely

Set one or more builds to be retained indefinitely.

 

Bonus Feature – Generate DGML for your build environment

This feature was outside spec, but since I was playing around with generating DGML it was easy to implement this feature and it is actually rather useful. It quickly gives you an overview of your build resources, e.g. which build controllers and build agents that exist for the current project collection, and on what hosts they are running. The command is available in the small toolbar at the top, next to the refresh button:

image

Here is an example from our lab environment:

image

The dark green boxes are the host machine names and the controller and agents are contained within them.

Note: Currently the only way to view DGML files are with Visual Studio 2010 Premium and Ultimate.

 

I hope that many of you will find this tool useful, please report issues/feature requests to the Community TFS Build Extensions CodePlex site!

December 2011 TFS Power Tools Release

Brian Harry just posted an update on the latest version of the TFS 2010 Power Tools. This will most likely by the last version of the Power Tools for the TFS 2010 version, next version will target Dev11!

The main improvements in this release are:

  • Team Foundation Server Power Tools for Eclipse
  • MSSCCI Provider for 64-bit IDE’s
  • VS 2010 Power Tools update
    • Improved Work item Search
    • Best Practice Analyzer now also analyzes the integration with Project Server, if you are using it

Check out the early Christmas gift here:

http://blogs.msdn.com/b/bharry/archive/2011/12/16/december-2011-tfs-power-tools-release.aspx

TF237165: Team Foundation could not update the work item because of a validation error on the server.

I often use the VS 2010/TFS 2010 evaluation virtual machines that Microsoft publishes every 6 months with the latest bits. It’s a great timesaver to use an image where everything is already setup and also contains a bit of sample data that is useful when you want to demo something for customers.

 

There is one thing that has always been a, albeit small, but still very annoying problem and that is that the builds always partially fail when you start using the image. When you want to demo the powerful feature of associated work items in a build, you’ll find yourself with your pants down since the build fails when trying to update the associated work item! Even when looking at the historical builds for the Tailspin Toys project, you will notice that they also partially failed:

image

 

If you look at the error message in the build details, you’ll see the following error:

 

image

The work item ‘XX’ could not be updated: ‘TF237165: Team Foundation could not update the work item because of a validation error on the server. This may happen because the work item type has been modified or destroyed, or you do not have permission to update the work item.’

The problem here is that the build agent by default is running as the NT AUTHORITYSYSTEM account, which is an account that do not have permission to modify work items. Your best option here is to switch account and use the Network Service account instead. Open TFS Administration Console, and select the Build Configuration node. Press the Stop link in the Build Service section:

 

image

 

Select Properties and select NT AUTHORITYNetworkService as Credentials

 

image

 

Press Start to start the build service with the new credentials.

 

If you would queue a new build now, the build would fail because of conflicting workspace mappings. The reason for this is that we haven’t changed the working folder path for the build agents, so when the build agent try to create a new workspace, the local path will conflict with the workspace previously created by NT AUTHORITYSYSTEM.

So to resolve this we can do two things:

  1. (Preferred). Delete the team build workspaces previously created by the SYSTEM account. To do this, start a Visual Studio command prompt and type:

    tf.exe workspace /delete <workspacename>;NT AUTHORITYSYSTEM


    If you need to list the workspaces to get the names, you can type:

    tf workspaces /owner:NT AUTHORITYSYSTEM /computer: <buildserver>

  2. (Less preferred, but good if you want to switch back later to the old build service account) 

    You can also modify the working folder path for the build agents, so that they don’t conflict with the existing workspaces. Click Properties on the build agent(s) and modify the Working Directory proprerty:

    imageb

    In this case, you can for example change it to $(SystemDrive)BuildsNS$(BuildAgentId)$(BuildDefinitionPath)  where NS = Network Service.

Compatibility Problem with Microsoft Test Manager 2010 and Visual Studio 2011

UPDATE 10.01.2012:

The issue has been resolved by Microsoft and will be addressed in patch soon. Here is the full description from the Connect site:

“We’ve identified the rootcause. This bug was introduced in the compatibility GDR patch released for VS 2010 to work against 2011 TFS Server. We shall be releasing a patch soon. Till then, please follow the workaround mentioned to unblock yourselves. “

When setting up a physical environment for a new test controller on our TFS 2010 server, I ran into a problem that seems to be related to having installed the Visual Studio 2010 SP1 TFS Compatibility GDR and/or Visual Studio 2011 Developer Preview

on the same machine as Visual Studio 2010 (SP1)

 

The problem occurs when trying to add a test agent to the physical environment, MTM gives the following error:


Failed to obtain available machines from the selected test controller.


Clicking on the View details link shows the following error dialog:

image

Error dialog: Cannot communicate with the Controller due to version mismatch

 

I have investigated the problem together with Microsoft, and they are working on finding out why this is happening. I have posted the issue on the Connect site here:
https://connect.microsoft.com/VisualStudio/feedback/details/712290/microsoft-test-manager-2010-can-not-communicate-with-test-controllers-when-visual-studio-11-is-installed-on-the-same-machine

 

Workaround

Fortunately, we found a workaround that is not too bad. When facing this problem, go the the Controllers tab that list all the controllers. If you select the controller from the list, it will actually show the test agent.

 

image

Then go back to the Environments tab and voila, the test agent appears now on the list. It seems like the

I’ll post an update when the issue has been resolved by MS

TFS 2010 Build – Troubleshooting the TF215097 error

Anyone working with developing custom activities in TFS 2010 Build has run into the following dreadful error message when running the build:

TF215097: An error occurred while initializing a build for build definition TeamProjectMyBuildDefinition: Cannot create unknown type ‘{clr-namespace:[namespace];assembly=[assembly]}Activity

What the error means is that when the TFS build service loads the build process template XAML for the build definition, it can’t create an instance of the customer workflow activity that is referenced from it.

The problem here is that there are several steps that all need to be done correctly for this process to work.

Make sure that:

  • When developing custom workflow, you keep the XAML builds template workflows in one project, and the custom activities in another project. The template workflow project shall reference the custom activities project.
    This setup also makes sure that your custom activities show up in the toolbox when designing your workflow.
  • You have checked in the modified version of the XAML workflow (easy to forget)
  • Your custom activity has the the BuildActivityAttribute:

    image

  • Your custom activity is public (common mistake…)
  • You have configured your build controller with the path in source control where the custom activities are located

    image

  • Verify that all dependencies for the custom activity assembly/assemblies have been checked into the same location as the assembly
    NB: You don’t need to check in TFS assemblies and other references that you know will be in the GAC on the build servers.
  • The reference to the custom activity assembly in the XAML workflow is correct:
  • xmlns:obc="clr-namespace:Inmeta.Build.CustomActivities;assembly=Inmeta.Build.CustomActivities"
    


But, even if you have all these step done right, you can still get the error. I had this problem recently when working with the code metrics activities for the http://tfsbuildextensions.codeplex.com/ community project.

The thing that saved me that time was the Team Foundation Build Service Events eventlog. This is a somewhat hidden “feature” that is very useful when troubleshooting build problems. You find it under Custom View

in the event log on the build servers


image

In this case I had the following message there:

Service ‘LT-JAKOB2010 – Agent1’ had an exception:

Exception Message: Problem with loading custom assemblies: Method ‘get_BuildAgentUri’ in type ‘TfsBuildExtensions.Activities.Tests.MockIBuildDetail’ from assembly ‘TfsBuildExtensions.Activities.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’ does not have an implementation. (type Exception)

Which made me realize that I had by accident checked in one of the test assemblies into the custom activity source control folder in TFS.


Unfortunately this whole process with developing you own custom activities is problematic and error prone, hopefully this will be better in future versions of TFS. Once you have your setup working however, changing and adding new custom activities is easy. And deployment is a breeze thanks to the automatic downloading and recycling of build agents that the build controller handles.

First stable release of the Community TFS 2010 Build Extensions

Today the first stable release of the Community TFS 2010 Build Extensions shipped on the CodePlex site. Visual Studio ALM MVP Mike Fourie (aka Mr MSBuild Extension Pack) has been the leader of this project and has done a tremendous job, both in contributing functionality as well as coordinating the work for the first release. Great work Mike! I (as well as several others) have contributed a small part of the activities, I plan to be working on the upcoming releases as well.

The build extensions contain approximately 100 custom activities that covers several different areas, such as IIS7, Hyper-V, StyleCop, NUnit, Powershell etc, as well as some core functionality (Assembly versionig, file management, compression, email etc etc). In addition to more activities in upcoming releases, the plan is to include build process templates for different scenarios.

Please download the release and try it out, and give us feedback!

To give you a hint of the content, here is a class diagram that shows the content of the “Core” activities project (there are several other projects included as well):

image