Intro
Building a project is no big deal. Building a solution of inter-dependent projects is also no big deal. Building multiple versions of the same solution full of inter-dependent projects and maintaining the association between source and binaries can get hairy.
NAnt and VSS
I have been working with NAnt for many months, VSS for many years. NAnt is the compile portion of an automated build system I've written that supports (hacks) the concept of “promotion” in MS Visual Source Safe. Promotion is the idea of tagging a file version for some target release. Using the latest code is not appropriate in a multi-project, multiple-release schedule team-environment
Requirements
The basic workflow is as follows... Developer makes changes intended for particular scheduled release and checks them into VSS. She labels the file with the build label (B1.15.02 for instance) and then notifies QA that the changes will be available in build 1.15.02. When QA is ready for that build, build application is executed using that label and all files labeled are collated and compiled. The result is checked into a staging directory section within VSS along with the associated source files and labeled as a snapshot. QA stages from VSS for test. When approved, infrastructure admins stage from the same location. Additionally, the build app can deploy the result. Anytime in the future, any build, from any project, compiled result and associated source, must be recoverable.
Additionally, we have outgrown building everything, every time. Reusable libraries need not be recompiled with the client but we still need to have the ability to restore the source code for the reusable library should that version require debugging. It would be nice if this were an easy, automated process.
NAnt solution task
I was excited to see all the additions NAnt has had in the last several months. I downloaded the last stable build and set up a test solution with a similar inter-dependent project configuration that we have in our real solutions. I was able to get <solution> task to work only after allowing full writable access to the virtual directory that held the web UI project. did not work correctly (supposed to map virtual directories to file path). Ultimately, it built the solution but did not copy resources such as aspx pages or images to the output directory. In fact, it ignored my specified outputdir and instead copied to the location of the build file. Perhaps it is a symptom of being on Win 2k Pro and using framework 1.0. I cannot control this, it is company policy that dictates what I use. So, while it did a good job of imitating what Visual Studio does, it does not provide a viable offline build solution solution....
NAnt contrib. Contains Slingshot, which converts a solution file to a NAnt build file. I’ve already done this manually but in the future may try it as a good starting place.
Automated Build System
Presently, my little build app can reconstruct any previous version of the application, compiled result and associated source, based on a holistic snapshot in VSS. That means build everything, check in all the source and result, label it. Done. Unfortunately, building everything, every time, gets cumbersome. So...
I am currently working on build application enhancements that enable a return to the versioned library build approach we were used to with Com and before. Each assembly will be built atomically, all by itself, independent of the projects it depends upon or which depend upon it. In out present application, we have assemblies that reference assemblies which also reference the assemblies the referenced assemblies reference. Uh huh. What if assembly (b) version 1.0 references assembly (a): version 1.2.0 and assembly (c) references assembly (b) version 1.0 and assembly (a) version 1.2.1 ? Furthermore, what if the development manager requests a restore of the solution as of 2 months ago? How do we identify what source code is associated with the dll in the bin directory of the client application? My plan is to label everything, embed the version in the assembly manifest and maintain a version specific reference configuration file in the source of each project. It's like reinventing the solution file. I would love to use the solution file but every developer has a little variation of the solution file. Some have project references, some use file refs, some have test projects and files. Getting everyone to conform is harder than maintaining a master file. I have the NAnt file, the traditional version that calls out what to build, what to copy, etc, in the source. I will now have the additional versioned references configuration file as well. I'd like to combine them but haven't decided if that is appropriate. It is better to have less files and fewer steps to set up but not at the expense of complication.
Back to the source-binary maintenance. When source for a project is reconstructed from VSS, the binary (actually IL, but you get the idea) will be in the bin. The ref-config file will tell the application where the source exists in VSS. The application can then go get that source. Wow, I just answered my question. I had a dilemma and the answer just appeared. So the config file includes the version. During the build, I will amend the config document so it reflects the exact version, including revision, of the referenced assembly. This will be accomplished using reflection. References will be pulled using a version label to whatever precision is appropriate. A reference might simply specify assembly (a) ver 1.2. Then, the most recent 1.2 will be retrieved (maybe 1.2.345.3211). How tightly specified the reference is should be flexible. I will read the manifest of the assembly, retrieve the version embedded, amend the config file of the client to reflect that, and viola, any previous state can be restored in the future.
This deployment process has been an amazing journey for me as it has changed so frequently. My hope is that Microsoft will consider these requirements with MS Build. The key to having a viable build solution is supporting the ability to promote files and keep working on them. While I love my little build app, I would gladly retire his position for something that MS supports. On the other hand, it sure was fun to build an app that builds apps including the build app. I wonder if I could add a code seeker to the build app and set him free in the world, randomly building applications all over the world…
nAnt
I will post my insights on NAnt at a later time. For now, some quick advice:
- Use the samples. Documentation is lacking but functionality is extensive. Check out the samples to see what is available.
- Start simple. Don’t try to build you company app right away. Make the hello world app that mimics your real app on a smaller scale. Keep it for future refinements and experiments.
- Check out NAnt contrib. They’ve radically improved the NAnt workspace so finding things is exponentially easier but I spent quite some time wondering why tasks wouldn’t work.
- Read the user lists
VSS build process II.jpg (43.15 KB)<< process diagram