one of the team leaders at the project complained that she is wasting her time in building the setup for the project we work on,

first I'll try to explain how we work, we are about 20 developers in 3 main team:

  • The infrastructure team (my team) 3 guys
  • The backend team
  • The front-end team (asp.net) 4 guys

offcourse there are analysts and all but for the matter of this post those are the three teams that produce code. each team produces a setup that the other teams need to install in order to produce code. each setup relies on the setup before it, we found that to be easier than just deploy dll's, we do all sort of stuff like installing services and registering dll's (we have some com stuff). so 3 setup's for each build, each build has it's own version (all the dll's have the same version).

the infrastructure's team setup is installed to a directory and puts a registry entry in:

[HKLM]\software\Microsoft\.netframework\AssemblyFolders - when putting new keys under this folder and giving the default value of the key a directory path, visual studio will show the dll's in that directory under the references screen. that's how different teams can find dll's from the infrastructure.

usually the infrastructure releases a setup only when needed or when critical updates are being made to the system, the other teams produces a build on a daily basis , the builds are going to the qa team which tests them and post bugs thru share point portal server.

about our version policy:

the infrastructure has a version template like this: x.y.z.0 , the backend has the same x.y.z and a trailing number mentioning the build, the FrontEnd guys work the same. so the backend and the FrontEnd specifically mention which version of the infrastructure they rely on. each team is checking in the setup into the source control.

after the team leader complained about the time it takes to get a build (about 15 min.) most of it because we're working with visual source safe and it's so SLOW. I started browsing for build servers ready for work in .net. I came across two that catched my eyes: BuiltIT from Microsoft and draco.net. I took a brief look at both and decided to test the first one because it looked simpler. draco.net has a service running and I wanted something simpler, like XCopy install.

basically what BuiltIT does is the following:

  • reading a version number from an xml
  • checkout a version file from the source control and update the build number
  • label all the sources of a given solution/project
  • get the sources using the label
  • bring up Vs.net to life and build it in debug and release
  • count the number of failed compilation
  • if it has more than one failed compilation it reverts all the code to the version before the label.
  • if it was successful it archives the dll's/exe's and send an email
it looked nice enough to start with. I didn't like the following:
  • it didn't support setup projects after the build
  • it was archiving all the dll's and exe's
  • it didn't support web project - since vs.net puts the web project under inetpub and not where the vss puts it
  • it has an odd copying policy for dll's , if you have 2 projects that have the same folder name you're in trouble because builtit will try to copy the outputs to the same directory, and if he finds a dll with the same name (let's say a shared dependency) it will fail to build.
  • when in release it doesn't copy the pdb files (DAH!!!!)
  • it supports incrementing only the 3rd number of a version file.
  • when sending emails it didn't put a sender email ( ;( )
  • it didn't produce any output out of Visual studio except for the number of project failed and the time of the compilation (DAH #2!!!)
  • when labeling it used only the build number and now the whole version number.
what I did like:
  • they wrapped all the Visual source safe interop into a nice api.
  • thay have a good flow and methodology
  • wrapped vs.net automation and have an option to choose which vs.net version to run(using progid).
  • all the things were configurable thru the config
I had 3 days total to do modification and come up with a good build tool that will make the teams happy. so I did the following:
  • added support for setup projects, now on every solution you can point to the setups on your source control and it will check them out before the build starts.
  • disable the archiving policy
  • all the dll's and exe are copied to a specific solution folder including all the referenced assemblies, and now it copies files on top of existing ones
  • sending email - now works , I'm working on adding support for msn messenger using IMClient from chris sells - should be a breeze.
  • the version policy is now configurable - you can change any number of the four.
  • the version number can be copied from a different source file and them increment it.
  • the labeling now specifies the full version number
  • the most important thing - when sending emails it now attaches the visual studio compilation output ( I'll post the later ) so if something was wrong you can know about it
  • support for web projects - custom get latest for specific folders in the solution to a specific location
  • disabled the release build - need to add support for the build thru config file.
so after each build we get a setup inside the source control and a directory full of dll's and exe's from that solution. now I had to solve the setup problem since I didn't want to automate the setup on each build, so I added the keys to the registry for the backend solution.
after trying the new build server on the infrastructure setup I went along to try the backend solution. first I did it manually using visual studio and I saw that everything was working fine. when I ran the build server on the backend setup nothing worked. now I know that BuildIT is using automation to activate vs.net, and it should work the same if I;m doing it by hand. thinking I screwed up the solution , I retrieved a former version and tried it too, but the same happened, when inspecting the vs.net output (which was a must) I noticed that references are not resolved- that's odd, when I opened vs.net all was fine but thru automation something was wrong. I looked into the sln file to see how it's being managed - it doesn't look nice, found nothing interesting there, tried to screw a little with vs.net automation, but nothing worked. as a last resort I opened one of the backend projects and looked into it, I didn't believe what I saw

AssemblyName = "Noga.MetaData.Shared"
HintPath = "C:\WINDOWS\System32\SPL\Noga\Noga.MetaData.Shared.dll"
AssemblyFolderKey = "hklm\dn\nogainrastructureserver" />
please notice the AssemblyFolderKey entry- Visual studio documented the registry key used to resolve the reference. and watching the key I put I noticed I had a type error. so I changed the key under [HKLM]\software\microsoft\.netframework\AssemblyFolders to be "nogainrastructureserver" and it all worked like charm. it seems that when using automation vs.net doesn't try to resolve references beyond what is in the csproj file. that took about 4 hours to come up with - made me happy for the rest of the day.
 
so now we have a build server that does all the magic in 15 min. for all the 3 setup's and even labels it according to the right version.
a few more things I came across on this little adventure:
  • the build server must have a synchronized clock - when you are using visual source safe and you are checking in files only the client clock matters - since VSS doesn't have a 'server' it's obvious. but when you are doing something like labeling it will label only the stuff that are checked in before you machine clock, so if you have a file checked in let's say 10 min. in the future (according to the vss) it won't get labeled.
  • IMClient is cool - gonna use it everywhere.
If I'll remember more I'll post it. if you want the source ping me and I'll put it on gotdotnet.

*update - just found that the creator has allready opened a workspace here, I mailed him and I'll post my changes in a few days.