Customize Team Build 2010 – Part 4: Create your own activity

by Ewald Hofman 29. April 2010 12:21

In the series the following parts have been published

  1. Part 1: Introduction
  2. Part 2: Add arguments and variables
  3. Part 3: Use more complex arguments
  4. Part 4: Create your own activity
  5. Part 5: Increase AssemblyVersion
  6. Part 6: Use custom type for an argument
  7. Part 7: How is the custom assembly found
  8. Part 8: Send information to the build log
  9. Part 9: Impersonate activities (run under other credentials)
  10. Part 10: Include Version Number in the Build Number
  11. Part 11: Speed up opening my build process template
  12. Part 12: How to debug my custom activities
  13. Part 13: Get control over the Build Output
  14. Part 14: Execute a PowerShell script
  15. Part 15: Fail a build based on the exit code of a console application
  16. Part 16: Specify the relative reference path

In this post I will show you how you can add your own custom activities. Debugging the customizations is not the best experience. In this post I will show you how I modified the build process template. If you have a better idea, feel free to ping me (because I am never to old to learn :) )

  1. Open a new visual studio 2010 editor and create a new solution with 2 projects (of type Class Library) called Template and BuildTasks. One of the projects is for the custom code and custom activities, the other one to modify the build process template.
  2. Add a project reference from the Template project to the BuildTasks project

  3. Add in the BuildTasks project a reference to the following assemblies:
    1. From c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0
      1. Microsoft.TeamFoundation.Build.Client.dll
    2. System.Activities
  4.   And add the following references to the Template project
    1. From c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0
      1. Microsoft.TeamFoundation.Build.Client.dll
      2. Microsoft.TeamFoundation.VersionControl.Client.dll
      3. Microsoft.TeamFoundation.WorkItemTracking.Client.dll
    2. From C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies
      1. Microsoft.TeamFoundation.Build.Workflow.dll
      2. Microsoft.TeamFoundation.TestImpact.BuildIntegration.dll
    3. From C:\Windows\assembly\GAC_MSIL\Microsoft.TeamFoundation.TestImpact.Client\
      1. Microsoft.TeamFoundation.TestImpact.Client.dll
    4. System.Activities
    5. System.Drawing
    6. System.ServiceModel
    7. System.ServiceModel.Activities
    8. System.Xaml
  5. Create a copy of the DefaultTemplate, call it CustomTemplate.xaml and put it in the folder where the Template project is located. Add the file to the project, and set the build action to XamlAppDef. If you don't see the XamlAppDef option, then add an activity to the Template project to add the correct references and then delete it again.
  6. Add to the BuildTasks project two folders called “Activities” and “Library”

  7. Right click on the Activities and choose Add –> New Item. Choose from the dialog to only show the Workflow templates. And choose the Code Activity. Give it the name DoExcitingThings, and close the dialog with OK

  8. In the code we see some interesting things. As we have seen in earlier posts in this series the build heavily relies on activities (such as this code activity) and you can configure activities with Arguments which can be set with the properties window. In the code you decorate every property you want to see in the properties window with the InArgument (or InOutArgument). When you want to get the value of this property, you must use the context to get the value. The property itself won’t hold the value!

  9. I have modified the class so we can see the purpose and usage of the different argument types

  10. We also have to indicate that our activity is used by the Build Controller and the Build Agents. To do this, add a using to the Microsoft.TeamFoundation.Build.Client and decorate the class with the following statement: [BuildActivity(HostEnvironmentOption.All)] 

    If you forget to specify this argument you encounter the error

    "TF21509:An error occured while initializing a build definition \CustomBuildTasks\BuildName:Cannot create
    unknown type '{clr-namepace:NamespaceName,asembly=AssemblyName}Activityname'."

  11. Build the solution
  12. Open the CustomTemplate.xaml file and open the toolbox. In the toolbox we see our new DoExcitingThings activity added.

  13. Drag ‘n drop this activity after the “Get the Build” activity.

  14. When you open the properties window you see the three arguments we have added to our exciting activity.

  15. Lets put in a textual value in all the three arguments

  16. There are errors for the two arguments that have an output value, because it needs to store the value somewhere. So to solve this, you must create a variable for the correct scope (see part 2) and use the variable as value for the argument. You can either set the value for the variable in the variable window itself


    Or you can use the Assign activity which you can find in the Primitives tab

  17. Finally add a WriteBuildMessage to show the values of the arguments after the DoExcitingThings activity.
  18. Save the changes and check-in your CustomTemplate.xaml.
  19. Now execute a build based on the CustomTemplate. The build will fail unfortunately with the following error message

  20. The build controller was unable to load our exciting Code Activity, which is obvious. It is pretty simple to solve this. Open the dialog to manage the build controllers. You can find it when you right click the Builds node for the team project in the team explorer

  21. This will open the following dialog

  22. Select the Controller and open the Properties

  23. You see there a box to specify the path for custom assemblies. This means that you need to have one common location where you store all the assemblies that hold customizations (or just use one assembly that holds all the customizations). Since the assembly is not added by default to source control, you need to add the assembly first to Version Control and then specify that path in here.

  24. Be aware that when you add a file to Source Control that it is marked read-only. So do not use the bin or obj folder! You might want to add some logic to the Post-build event in the C# project to automatically create a copy of the assembly and automatically check it in to Version Control.

    You can use for example the following Post-build event:

    "$(DevEnvDir)\TF.exe" checkout "$/CustomBuildTasks/BuildProcessTemplates/CustomActivities/$(TargetFileName)"
    xcopy /y "$(TargetPath)" "$(SolutionDir)..\..\BuildProcessTemplates\CustomActivities"
    "$(DevEnvDir)\TF.exe" checkin "$/CustomBuildTasks/BuildProcessTemplates/CustomActivities/$(TargetFileName)"
  25. When you now run the build, you will get the following result in the build log



You can download the full solution at It will include the sources of every part and will continue to evolve.

Tags: ,

Team Build | VSTS 2010

Powered by BlogEngine.NET
Theme by Mads Kristensen


Widget Statistics not found.

There is an error in XML document (0, 0).X

Recent comments

Comment RSS