I was recently out on StackOverflow and ran across a question that boiled down to, “When should I write an MSBuild Task to fulfill a build need and when should I implement a TFS Code Activity?” I answered the question there but the more I thought about it, I felt it warranted a blog post to expound on the topic a bit more.
Given the many ways to fill a gap in build process today and the many technologies available, the StackOverflow user’s question is a great one. How do you decide between coding an MSBuild task and a TFS Code Activity? There are a variety of questions you should ask yourself when deciding between MSBuild and Workflow activities. Here are the questions:
1“Does MSBuild support this functionality out of the box?”
This may be the most obvious question, though its one that get’s overlooked from time to time. Code Analysis (see FxCop) and file copying are great examples of items that come right out of the box with MSBuild. Don’t confuse this with the plethora of 3rd party MSBuild tasks out there such as the MSBuild Community Tasks and the MSBuild Extension pack. These are custom tasks just like the one you may be about to develop. Obviously having a free 3rd party solution in MSBuild already complete may sway you, I still encourage you to ask yourself the rest of the questions.
2“Does the build action need to run on developer boxes as well as servers?”
This question is really important. Do you want your developers invoking this action? If the answer is no, such as in the case of Code-Signing or Version Incrementing, then I’d suggest moving the build step to a server-side activity to ensure they don’t have the opportunity. if the answer is yes, such as in the case of Packaging MSIs, add the build step into your MSBuild system in a way that allows toggling it on and off and also allows reuse in other areas where possible.
3“Does the build step need to interact with TFS API or source control directly?”
This question goes hand in hand with the previous one. Do you want your development team checking out & in a version file for incrementing or invoking some customized labeling step? Even by mistake? Probably not. Moving this type of build step into a TFS Code Activity also ensures that it can’t create another point of failure or speed degradation in your developer build, which they will appreciate. Finally, the reality is that any source control related task is likely going to have better integration with TFS if you leverage the workflow variables available during a TFS Build Workflow.
4“Are you going to change build orchestrators later to something else?”
Once again, this is quite important and obviously hard to predict. If your team has a full MSDN licensing investment and lives entirely on the Microsoft stack, you can pretty much bet the bank that you’ll stay with TFS. In addition, the TFS 2012 now supports Git as a source control engine so you can still go to distributed version control if you like and stick with TFS. However, if cost is an issue and you might jump to something like TeamCity or Jenkins, then staying away from custom TFS Code Activities or at least providing a layer of separation between core logic and the facade of the Code Activity is a good idea.
Combining the answers to all of these questions should inform and guide the implementation of any tool integration into a .NET build system.
I implement any tool that should be ran on a developer box build via MSBuild and use the new CodeTaskFactory facilities to write the C# directly into an MSBuild Tasks file where possible to avoid compiling binaries and checking them into source control or distributing them to team members via some other fashion.
I implement build steps such as version incrementing, customized bin-placing and CI deployment invocation (i.e. deployment of a SharePoint web-parts as a post-build step) via TFS Code Activities or some script ware, preferably PowerShell.
For those curious, the original StackOverflow question is here.