After having released time cockpit 1.0, we
decided to
finally upgrade to Team Foundation Server 2010. The upgrade seemed to
have worked without any problem and day-to-day work continued as normal
with checkins, branching and merging working at least as good as before.
If you read of the changes between TFS 2008 and TFS 2010 (here) you may have
noticed that TFS Build 2010 is based on WorkFlow 4.0 (WF4). While it
still works to use our existing MSBuild based automated build system, we
do not get all the fresh, exciting features TFS 2010 brings. Since
things are quite calm, I decided to take a look at it and port our build
system to WF4.
While MSBuild was based on
the notion
of tasks and project files inheriting and overloading tasks, WF4 is
based on the concept of activities. You can sequence activities, execute
them in parallel, etc. One of the very nice things about WF4 is it's
type safety and kinda-compilation. With MSBuild I often started a build
just to find out that at the end, you mistyped a variable name and it
expanded to an empty string. This is ok, if you build a few small
projects and your build is short, but here it means half an hour of
keeping your fingers crossed. WF4 definitely accelerated this process.
One of the big annoyances is a bug in the WF
editor. If
you drop in a ForEach<T> loop as an activity at first everything
seems to work fine. You add your within-loop-sequence, try to add some
variables, etc. Great. Save the workflow, close the document, open it
again, peng: gone. Nothing is saved within. It took me some time with
our favourite search engine to stumble over this blog
post. After this I ended up adding some xaml to every ForEach I
added.
So after having added a ForEach loop
you usually have something like this in your code:
<ForEach x:TypeArguments="x:String" sap:VirtualizedContainerService.HintSize="287,206"
Values="[configFiles]"/> What you actually want is this:
<ForEach x:TypeArguments="x:String" sap:VirtualizedContainerService.HintSize="287,206"
Values="[configFiles]">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="configFile" />
</ActivityAction.Argument>
<Sequence>
<!-- Do something with configFile available as variable here -->
</Sequence>
</ActivityAction>
</ForEach>
After having added those lines to your ForEach you can save the file and open it up in the visual workflow editor again. You can also modify the sequence from within the editor and it will work fine.Other than that I do appreciate WF4. The type safety, a graphical overview about what is executed, .NET class types (very nice for formatting). And learning WF has more use cases than just build automation, making my time spent learning WF worth it. Now if they could only get C# instead of VB for those expressions...