In this presentation I cover some techniques to extend the base build of TFS Build 2010, showing the interation with MSBuild and creation of custom activities.
3. MsBuild Activity Use a MSBuild Activity to call MSBuild wrapper around a Custom MsBuild task
4. MsBuild Activity Use a MSBuild Activity to call MSBuild wrapper around a MsBuild task
5. MsBuild script isinserted in a subdirectoryof the source controlpathof the project. Itis a simpleMsBuildFile.
6. The project file is a simplemsbuild file, it can contain standard msbuildtasks, or custom tasks. All custom tasks are included in the source control system and can bereferencedby relative path.
7. Locate the point in the workflowwhereyouwanttoexecute the custom msbuild project, and dropanMsBuildActivity.
9. To pass parameterto custom action, youneedtouse the /propertyswitchofMsBuildcommandline, allpropertiesneededbytasks inside the MsBuild file shouldbepassedthis way.
10. Configure the restof the MsBuildaction, specifylogFileDropLocationtospecifywhere the logfileneedstobelocated, specifyTargetstobuild, and give a UserFriendly display nameto the action.
11. At the end of the build, the log ispresent in the same directory of the mainMsBuild log file. In the log file you can seeall the output of the custom task, in thisexampleyou can see the xml answeroftwitter service.
13. Deploy a database project Locate the pointwhereyouwant the deployto take place, I placedafter test run, and I deployonlyif the compilation phase and test phase are bothgood. The CovertWorkspaceItempermits me tospecify the database project using a source controlpath, thatwillbeconverted in localpath. I alsocreated a dbProjectvariableusedtostore the output of the ConvertWorkspaceItem
14. Todeploy a database youneedtospecify target Deploy, do notforgettospecify a logFiletoverify the outcomeof the task. All the optionsshouldbespecifiedwithCommandLineArguments "/p:TargetDatabase=NorthwindTest" + " /p:""DefaultDataPath=C:ProgramFilesMicrosoft SQL ServerMSSQL10.SQL2008MSSQLDATA""" + " /p:""TargetConnectionString=Data Source=10.0.0.99QL2008,49400%3Buser=sa%3Bpwd=Pa$$w0rd""" + " /p:DeployToDatabase=true"
15. As for custom MsBuild task, during the build the output file is the best way tounderstandwhatishappenedduring the build.
19. The assemblies with your Custom Activities should be located in a specific path of the Source Control System. You have only one location where to store your customization, but this is usually a good practice.
22. Include a custom action in a workflow Create a project with the Custom Action Include a test project whereyouload the buildworkflow (I usually create a branchof the file) Nowyou are abletodrop the Custom Activity inside the workflow Alternativelyyou can simplyedit the workflow file withan XML Editor
23. Whenyou include the workflow inside a project, contained in the samesolutionthatcontainsalsoyour Custom Activity, you are abletoinsert the custom activity inside the workflow.
24. Youcannot open anymore the xamlworkflow, in the originalBuildProcessTemplate folder. You can stilledititwithan XML Editor.
25. Thanksto custom activityyouhave a better design experience, all input parameters are passed in a clear and coincise manner, you don’t needtouseMsBuildcommandline /parameteroption
26. Logging inside a Custom Activity Since the buildisnotruninteractively, a good log is the best optiontounderstandwhatisgone wrong in case ofanerror. Log asmuch information asyou can, to help people identify the real cause of the failure. Use log levelwithgreat care, so you can choosefrom the mainworkflow the verbosityof the actionduring the build.
27. Withthissimplemethodyou can add a log message in the build output. The BuildMessageImportanceidentify the importanceof the log, it can havethreevalue: High, Low, and Normal.
28. You can choose the BuildVerbosityfrom the Argumentsof the build, withthisoptionyou can decide wichlevelofLogswill flow into the build log. Ifyouusethisparameterwith care, you can avoidtoclutterbuild output withunusefulmessages, butyou can raise the verbosity in case ofanerror, tobetterunderstandwhatisgone wrong.
29. In the build log detail, each action automatically logs its name when it is executed. If the action create a log with the aforementioned method, the message is inserted after the action, the indentation helps to understand the action the message belongs to.
30. Differenttypeof log You can log not only simple messages but also warning and errors Both of them are inserted with the BuildInformationRecord class but they are different from a simple lot
31. A warning is reported in the Build Summary, inside Other Errors and Warnings section They are more important than log messages, and they should be used to communicate messages that needs immediate user attenction
32. Log Messages, even with High BuildMessageImportance, are always showed like normal messages. Warnings have a warning icon that differentiates them from standard messages even in the detailed build
33. When you issue a BuildError, the entire build is considered in Partially Failed State. The error is showed in the View Summary as well in the View Log, with a red icon to identify a real error that is happened during the build.
34. Custom Activity that wraps a Custom Task Create a Custom Code Activity that internally uses a Custom Task
35. Wrap MsBuild task in Custom Activity Wrap MsBuild custom task in a custom Workflow Activity
36. Wrap MsBuild task in Custom Activity Wrap MsBuild custom task in a custom Workflow Activity
37. This is an example of a Custom MsBuild Task that reduces the size of an Url with TinyUrl service. We have a couple of problems here. The first one is how to grab the value of the output property TinedUrland pass it back to workflow environment; the other one is how to “fool” the CustomTask that he is running inside a MsBuild environment. Another important aspect, is how to include log messages issued by the Custom Task inside the build log, and not in a txt file in drop folder
38. Custom Activity IBuildEngine Logs Workflow BuildEngine CustomTask Property CustomTask A CustomTask interact with the MsBuild environment through an interface called IBuildEngine. In the previous code, the call to Log.LogMessage flow into a concrete implementation of IBuildEngine. The trick to intercept log messages is to build a custom implementation of IBuildEngine
39. The WorkflowBuildEngine class implements IBuildEngine and contains a CodeActivityContext that is used to interact with the workflow Log functions are implemented with a simple call to Utility function seen before. With this trick all call to Log inside the Custom Activity will flow into the workflow log.
40. This activity inherits from CodeActivity<T> where the type argument indicates the return value Inside the activity I create an instance of the Custom Task, populate all input properties, as well as the BuildEngine property. Then I call the execute method and if it returns false (the custom task encounter errors during execution) I log an error, and finally I returned the value of the output property of the Custom Task
41. You get a better design experience, property are populated through the designer. You can assign the value of result property to a property of the Workflow, you are able to grab output properties of Custom Msbuild Task. Remember to deploy the dll with the custom task in the same folder as the assembly that contains custom action
42. All Log.LogXX calls made inside the MsBuild Custom Task are intercepted and transferred to Workflow. Not only messaged, but also warnings issued by Custom Task are correctly identified as Warning in the build result. With this technique you do not need to look at the text log file to understand what is gone wrong during the execution of the Custom Task.
43. Custom activity Instead of code something, create a new activity composing multiple simple activity to accomplish a complex task Es. Deploy database, instead of using directly MsBuildActivity
44. Using “arguments” you declare all input arguments needed by your action. In the property windows you can set type, direction and IsRequired property, you can also specify a default value
45. This example shows how to create a custom action that deploy a database project using the same technique seen before. The only difference is that all the steps are included in one action to have a better user experience during customization
46. Logging is easy, because you can simply use the WriteBuildMessage activity from the “Team Foundation Build Activity” list. The log of database deployment is still done by MsBuild in the standard file located in drop folder.
47. Instead of using several activities, you can simply drop a single one and you can configure parameter explicitly. Each parameter to the deploy operation is represented by a specific property, and each property can have a default value.
48. Compare how easily arguments are passed with a Custom Activity respect using directly the MsBuildActivity
49. Move the logic into a poco class Put the logic inside a POCO class, then build a MsBuild custom task and a Custom Activity
50. Take the best of both world Extract the logic into a POCO class and create wrappers
51. Take the best of both world Extract the logic into a POCO class and create wrappers
52. A real scenario Create a custom build to automate the deployment of a web app in a test server The script deploy the database project and change the directory in IIS to point to the drop folder TFS Update IIS Check In Sync DB Build Server DB Test
53. You can obtain this from the previous example “Deploy database with Msbuild”. The only added part is another Custom Activity used to change the folder of a site using WMI to communicate with IIS