Wednesday, March 10, 2010

Single Installer for multiple environments

With quite a few contracts I have been working on over the years I have ended up helping out with the build process for ASP.Net websites. Many existing enterprise build processes I have encountered tend to involve making a custom build of the codebase for UAT and then once UAT is passed making another build for PROD. This process brings in a significant risk of a developer on a team checking in changes AFTER UAT was build and thus ending up with untested code in PROD.
This risk is unnecessary. The following is an approach I have used at a number of enterprises for creating a single .msi installer which can be run in a DEV environment (if it exists), then copied into a UAT environment for user testing before finally being copied and run in PROD. The single installer gets built once but can handle the different server/database configurations of the different environments and can install the correct .config files in each environment.
The methodology is as follows:
  1. Within Visual Studio, add a Setup Project to the solution
  2. Create different copies of the Web.config for each target environment. Each web.config (e.g. web.config.UAT) can then be tailored to each environment. You should end up with a project similar to the following:

  3. Change the Properties of the original web.config and set its "Build Action" to "None" 
  4. Right-click on the Installer project and View -> File System
  5. In the Application Folder, add the new web.config files (DEV, UAT and PROD). You should end up with the following: 
  6. For each of our three files set the following properties:   

Transitive: True
Vital: False
   ->Replace "DEV" with "UAT" and "PROD" for the other configs 
TargetName: web.config

    For example with the UAT file: 
Then, when installing at each environment, use similar to the following at the command line:
msiexec /q /i "Installer.msi" ENVIRONMENTNAME="PROD"

The ENVIRONEMNTNAME flag which is passed into msiexec tells the installer to use the file(s) marked with the same Condition property (step 6 above). Thus, the right config file gets chosen for each environment. I have used this approach successfully many times with Visual Studio 2003, 2005 and 2008.
Hope its of help!