Mark Gilbert's Blog

Science and technology, served light and fluffy.

Subversion stepping on its own toes

Last week I hit an interesting issue with one of the projects running under our CruiseControl.NET build server. Before I get into the specific, I need to lay out some of the structure.

 

“He’s hitting me!”

Nearly all of the public-facing sites that my company builds have some element of Flash to them. The Flash source code and especially all of the assets that get rolled in to a finished SWF take up quite a bit of room on the hard drive.

We learned pretty early on that pulling all of the Flash source code down to the build server was a waste of time because 1) we had limited space on the hard drive and the Flash assets took up a LOT of room; and 2) NAnt wouldn’t do anything with it – the Flash team was already compiling the SWFs for us and committing them to Subversion. All we were doing was copying them (via NAnt) from the folder that the Flash developers were using and put them in the /swf folder below the site web root. So, we switched from using a single <sourceControl type=”svn” /> block to using <sourceControl type=”multi” /> (http://confluence.public.thoughtworks.org/display/CCNET/Multi+Source+Control+Block), and cherry-picking which folders in Subversion we would pull from.

1

A couple of weeks ago, one of my colleagues, Joel, suggested that we could have CCNet pull the compiled SWFs down from Subversion, and drop them directly into the /swf folder below the site root on the build server. That would save a step in NAnt, would allow the overall process to run slightly faster (by not copying the SWFs), and would help to conserve room on the hard drive (by not storing two copies of the SWFs).

2

I thought that was a good idea, and I retrofitted one of my projects to use that new process. It seemed to work great.

 

“No, me first!”

Now, as many of you know, we come to the point of the blog post where the author reveals “TheCatch”.

When I tried to use the same modified on a completely fresh project – one where none of the directory structure on the build server existed yet – CCNet through this error: “Failed to add directory ‘wwwroot’: object of the same name already exists”.

My first thought was a case-sensitivity clash. Subversion is case sensitive but Windows is not, so it’s possible to have two folders in the former such as “mybranch” and “MyBranch”, but my Subversion client will have fits when it tries to being those down to the latter. After checking the repository and the working folders on the build server, everything matched just fine. When I stopped and thought about it some more, I realized this probably couldn’t have been the cause since the build script for the new project was nearly a direct copy of one for a previous project – a previous project that had been running smoothly for weeks.

 

“Do I have to split you two up?”

I decided to fall back on a tried-and-true method of troubleshooting – comment out successive chunks of code until the error goes away. I had two <svn> blocks in the CCNet.config file, the first for populating the MyBranch/site/wwwroot working folder, and the second for populating the MyBranch/site/wwwroot/swf working folder. I removed the latter and re-ran the project. Lo and behold, it worked! I then replaced the second <svn> block and ran it again, fully expecting it to fail again. Shenanigans – it STILL worked! I blew away everything under the MyBranch in the working folder on the Build Server, and made sure I could reproduce this. Sure enough I could.

I began to suspect that the source of the problem was that I had one working folder being placed inside another. Up to this point, I had been assuming that the <svn> blocks were executed sequentially, and in the order that I placed them in the ccnet.config file. Perhaps they were being processed in reverse order. If that was the case, then the Flash source would get pulled down first, and the Subversion working folder of “swf” would get created in a “regular” folder structure of MyBranch/site/wwwroot. Then, the first <svn> block gets processed, and that tries to create a Subversion working folder for MyBranch/site/wwwroot. Since that folder already exists as a regular folder, it chokes.

When I removed the second block, the “wwwroot” folder was able to be established as a working folder. Then when I added the second block back in with “wwwroot” already there, it didn’t have a problem with adding another working folder as a subfolder.

I haven’t been able to find a way to force a specific execution order on the <svn> blocks. It may be that they get executed in reverse order every time, or that they get executed deepest-level-first, or that it’s not deterministic at all. At any rate, the hack that I settled on was running the project through once with just the first <svn> block to establish “wwwroot” as a working folder, and then adding the second block to get the rest. This is only an issue when the build project is first being configured, so I don’t feel overly terrible about handling it this way.

Advertisements

September 10, 2009 - Posted by | Agile

Sorry, the comment form is closed at this time.

%d bloggers like this: