I wouldn't call it a rule that the two areas of a project that never get enough attention are build optimization and deployment, but it's pretty close.
A project's build process usually seems to evolve as a consequence of the day-to-day development, rather than as the result of a focused plan. No one looks at optimizing the build until it becomes a problem. On the other hand, everyone knows the deployment process is important but always underestimates how long it will actually take. Right now I'm doing a lot of work to automate a deployment, so this post is going to focus on that, outlining a few of the things that I've learned and some resources that I'm using.
You'll notice that I also include continuous build in some of the below discussion. I know that's technically part of the build, not the deployment, but it's included because being able to get a working, up-to-date build is perhaps the most important part of deployment. Also, Microsoft's new MSBuild is flexible enough that it is increasingly able to handle deployment tasks. Lastly, most of the stuff I'm talking about can also apply to installation of an application, but since we are using it for deployment of a web site, I'll continue to use the term deployment.
The first step is to figure out what you need to do. Whatever you're installing probably has dependencies. Does it require users to be setup? Do you need to install anything in the GAC? How about the registry? Are you deploying a web site? How about a database? What are the permissions for all of that? Each tiny detail can break a build or complicate a deployment. Automating your build and deployment steps is a way to fix these problems once and have them stay fixed, rather than revisiting the same nightmare every time you need to change the width of a textbox. Plus, remember Joel's second step to better software:
2. Can you make a build in one step?
I think this applies to deployment as well. Nobody needs an eight hour marathon session of copying files and editing XML every week or two.
Continuous Build with Cruise Control .Net
To give you some background on our environment, as I talked about earlier, we're using Cruise Control .Net to implement continuous build. TFS 2008 is going to support continuous build in the future, but Cruise Control .Net is a great option for now. We were able to get Cruise Control .Net to incrementally pull the latest source code from TFS as necessary and do continuous builds going using the out-of-box MSBuild task (set up with the downloadable MSBuild XML Logger) and the Team Foundation Server add-in.
Looking at Deployment Options
So, let's take a look at some of the most obvious solutions for deployment.
- The project is using Visual Studio 2005 and the much loved and hated Web Site project in VS2005 includes a Publish Web Site option. This is an easy way to do an xcopy deployment of the site, but it doesn't really handle any advanced deployment needs (permissions, etc).
- There is a Web Deployment Project add-in for Visual Studio 2005 that is customizable and based on Microsoft's new build system, MSBuild.
- MSI's provide the flexibility we need but require a lot of custom work, even to replicate some of the out-of-the-box functionality of the web deployment projects.
- Other tools like NANT and WIX provide a lot more deployment options but usually with vastly higher learning curves.
After some research, our project was set up to use a web deployment project for it's ease of use and flexibility using MSBuild. Deployment to a small number of servers doesn't usually warrant the initial investment required for using some of the more advanced tools.
The Web Deployment Project and MSBuild
MSBuild has some impressive functionality and the community support around it is already making it a viable build alternative in my opinion. However, with the web deployment project there are some things to keep in mind:
- Web deployment projects are full MSBuild projects. They are fully customizable with MSBuild tasks and include their own set of extensions to MSBuild for tasks such as GrantServerAccess (which grants access to the deployment path for the ASPNET user).
- Web deployment projects are not supported in Visual Studio 2008 yet. The latest comment from ScottGu says they will be supported at some point in the future.
- In VS2005, web deployment projects are not meant to be used for one-click deployment to remote servers. Another comment from ScottGu (from last year) recommends using the Publish Web option to deploy a site to a remote server and says that significant features will be added to this area later.
Using and Customizing the Web Deployment Project
There isn't a huge amount of documentation on some of these items so here are some good links to get you started:
If your project requires a lot of customization to the web deployment project, you're going to need to get familiar with MSBuild. The main documentation is readily available here, but it's not easy to navigate. I printed out the the central list of build tasks and the MSBuild reserved properties list and went through both with a hi-liter to see what I could use.
By default MSBuild comes with a lot of standard tasks like EXEC (for executing a command). You can also write your own MSBuild extensions (tasks, etc.), however there are some great extensions out there already. As I stated earlier, the web deployment projects come with their own set of MSBuild extensions that provide very basic functionality for deploying a web site. Another great resource is the msbuildtasks project over at Tigris.org, an open-source project that expands MSBuild even farther with a large number of tasks for working with VSS and Subversion, manipulating IIS, interacting with SQL Server, running external tools like FXCop and even compressing Java files. The tasks that I tried worked very well with a few caveats:
- Some of the tasks only work on IIS 6.0 right now. Since most deployment environments are Windows Server 2003 running IIS 6.0 and you can't get a production version of IIS 7.0 yet, this is fine but it can complicate things if your development machine is using IIS 7.0 (I'm looking at you, Vista).
- The msbuildtasks documentation is seriously lacking. Searching the Internet for information about one task I was trying to use turned up a total of 7 results. 3 of those were from the Tigris.org source code. I think the rest were in Chinese. Ouch.
Using the msbuildtasks extensions will require a bit of trial and error but the end result is definitely worth it. The project is a great step down the right path.
If you get this deep into your build and deployment process, you will probably also need some good command line references. Some good sources of information I used:
I'm actually pretty impressed with the results I've seen using MSBuild. The tasks are relatively straight-forward, the logging is great (TIP: switch the output setting to Detailed under Options > Performance & Build > Build in VS2005), and the build process seems as fast or faster than building MSIs. With the burgeoning community support, it could definitely be a very robust build tool. Good luck.