Msbuild is microsoft build engine, and I showed some time ago how you can write a custom task to post in twitter the outcome of a build result. Now it is time to give a greater focus on how to write a good task.
Creating a Task is a simple matter of inheriting from the Task class but there are some key points you should keep in mind, first of all you should never throw an exception when executing the task, except for some specific system exception like OutOfMemoryException or StackOverflowException, then you should provide good logs to make simple for the user of your task to understand causes of failures.
Some of the tasks I miss most from transition to Nant to Msbuild is the couple XmlPeek and XmlPoke, used to read and manipulate xml files with xpath. Replicate them with LINQ to XML is a breeze. To actually build the task I first included all the logic in a different class.
With such an arrangement I can easily test my XML logic
After you have carefully tested your logic function it is time to test logic of the task, here is the full code of the task.
I enclosed the main body of the action in a try catch, but I need to rethrow exceptions that really cannot be catched. Then for every other exception I simply log it and then return false to the caller. For the main path of the action you should carefully validate input parameters, and give detailed error with the Log property from Task base class. Since good logs are really important, you should test them carefully.
Thanks to Rhino Mock I create an implementation of IBuildEngine to pass to my action to simulate the msbuild execution environment, then I call my task with a file name that does not exists, and verify that the LogErrorEvent was called in the BuildEngine.