Lessons Learned

Topics: User Forum
Feb 23, 2007 at 7:25 PM
Edited Feb 23, 2007 at 7:28 PM
I just posted my thoughts on CCnet + TFS in a blog post. Hopefully others will find my experience useful.
Feb 23, 2007 at 9:33 PM
Hey Brad,

Thanks for doing that. I was wondering, can you explain why you opted for it to delete the workspace every time? Also, why you think a workspace per project works best for you?

Also, if you wanted you can just register the necessary assemblies in the CAC rather than loading the whole Team Explorer client on the build machine - would you like me to share more details on that?

By the way, there are many reasons why I opted to go use the API rather than going direct to the web services - the main one being is that the API integration is a supported route from Microsoft allowing better forwards compatibity as new versions of TFS come out. I am very familiar with talking directly to the TFS web services and it is something I would advise against unless you really have to.

Thanks for taking the time to share your experiences on using the plug-in.


Feb 23, 2007 at 11:21 PM
The desire to have the workspaces cleaned up is because they feel like they should be transient to me. If you didn't think I should do it, why did you offer me the option? :)

I need a workspace per project because of the deletion option.

In my experience, the client object model is pretty darn buggy. This is what we've been running into (cache information is out of date with reality and causes failures that shouldn't be there). If you used the web service API (whether you decided to use workspaces or not), it would've prevented the headaches.

I understand that GACing the DLLs is valid, but you don't have access to them without downloading that quarter gig .img file. :) Again, using the web service API would allow you to avoid the dependency.

Just my 2c. :)
Feb 24, 2007 at 2:45 PM
Apologies if my previous post came out as being critical of your approach - I'm not at all, just interested why you were doing things in case there were some bugs or things I could make better. Thanks for providing more info.

Originally, I used to also have the workspaces deleted - in fact in V1 of the plug-in this was the only way it would work - however I added the ability to re-use workspaces due to feature requests. I think the ability to do both is a good compromise.

Keeping the workspace around does allow you to take advantage of a lot that is good about TFS. The main one being that it massively reduces network traffic required. TFS is very good at removing files that were deleted / renamed / moved etc so you don't get into the issues that you might be used to from VSS / CVS / Subversion when not doing a clean get.

I now understand why you needed one workspace per project - because of the delete thing. Again, keeping the workspace around would save you from having to do that (but you know that :-) ). I would urge you to try running with keeping the workspace around for a while - in my experience it has worked out as the best way, but like you say - keeping both ways of working around gives folks choice.

My justification for the GACing the TFS client assemblies is that you probably already have them installed on your development machine to allow you to be checking in to TFS in the first place so you can copy them from your VS/IDE/PrivateAssemblies folder onto the build machine and register them. Due to re-distribution rights I wasn't able to provide an MSI that did this for you - however I'm still trying to figure out a way of making it easier.

I have to disagree with you about the Microsoft Object Model being buggy, I personally find it very stable. While I know of a couple of bugs in the Visual Studio UI, I am not aware of any in the version control API's - especially not the ones exercised by the CCNET plug-in. If you have details of any bugs that you have found then please send them along and I will pass them on to the team.

From experience, writing a client that talks to the web services directly is likely to have a lot more bugs in it first time around than using the heavily tested one from Microsoft. It is also hard to get the same level of performance when talking direct to the web services - the Microsoft API has a custom generated web service proxy that does lots of tricks to maximize the available network connectivity and reduce the ammount of data wasted during NTLM authentication.

Another reason for using the API is that if a company were to find a problem with the communication to TFS from CruiseControl using the API then they can ring Microsoft Support and get the API fixed. Official Microsoft support was very important for the company I was working for at the time I wrote the plug-in.

The dependancy with the API has caused other issues though - such as not being able to integrate the code in with the main CruiseControl.NET project is the main one. The argument that talking direct to the web services would allow the code to be part of the CCNET codebase is one I would find harder to disagree with.

However, I was thinking about a couple of alternatives that would still have the advantage of making use of teh Microsoft API. One way I was thinking about getting around this by calling the API via a reflective wrapper rather than compiling against it direct. It's a bit of a nasty hack but will allow the TFS integration code to go into the CruiseControl.NET mainline and allow the code to talk to a supported integration point from Microsoft.

Another approach would be to talk to TFS via a wrapper around the tf.exe command line. This however makes the install dependancies higher (so meaning you cannout just copy over the assemblies and register them in the GAC). Additionally, parsing of the TFS command line is more complicated if you want it to work for all localized versions of the CLC. However, communication via the tf.exe command line is actually how I've implemented the integration between CruiseControl (java version) and TFS and it works pretty well.

If you fancy having a go at talking to the web services direct, then be my guest. It is actually something I have a good deal of experience with so I'd be able to provide you some pointers if you wanted. However, for many reasons (including the ones mentioned about) it would not be the integration path I would personally choose for a .NET application.

Anyway, thanks for the feedback - I do appreicate folks who take the time to get in touch. It is always welcome to have a conversation with someone who is using the integration and helps motivate me to create new and improved versions.