nzduck
nzduck

Reputation: 476

How do I handle multiple Visual Studio configurations when doing continuous integration?

I have multiple configurations set up in Visual Studio so that I can build one solution (containing multiple projects) for one of a number of customers. A small number of web.config settings are customized depending on the customer, and the code is built to a different 'BuildDir' so I can package it up and deliver it. At the moment this is all driven from the Visual Studio Configuration Manager on my dev machine in conjunction with a couple of Web Deployment Projects, and I'm finding this pretty fragile.

I want to implement a CI server (CC.Net or TeamCity) but am not sure how to best accommodate this sort of per-client configuration (or if I should be attempting to). I develop in a branch, and reintegrate with the trunk as each feature is completed. Am I correct in thinking then that the CI server should be integrating the code in trunk, and if so, how do I deal with debug and release builds for each customer?

My configurations are:

Apart from the small number of configuration settings for each customer the product is pretty much the same for all of them.

I'm keen to get your thoughts on how I could set this up, or whether I'm thinking about this wrong?

Thanks.

Upvotes: 1

Views: 545

Answers (2)

nzduck
nzduck

Reputation: 476

I solved this using UppercuT, RoundHousE and CC.Net, and by changing the way I branch and tag the various configurations in SVN. Now I have one 'mainline' of code (the trunk) that is automatically built by CC.Net/UppercuT on the build server and is then made available for packaging and deployment using UppercuT. If I need to build a specific customer's source, I can get their source, make the necessary change, and then commit back to their branch. Running UppercuT within that branch then produces a deployable package for that customer. The combination of UppercuT and NAnt provides much greater flexibility IMO that using VS2010's Configuration Manager.

Upvotes: 0

Andriy K
Andriy K

Reputation: 3407

We adhered two-step building procedure: first solution is build normally with Debug/Release configuration. Next (after build completion procedure), task is run for transforming web.configs(this if for one file, but it can be easily fixed to handle bunch of them):

<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
<Target Name="TransformWebConfig">
    <TransformXml Source="$(WebFolderName)Web.config"
        Transform="$(WebConfigsFolderName)Web.$(WebConfiguration).config"
        Destination="$(WebFolderName)Web.config" />
</Target>

This way
1) You have only two meaningful configurations in solution file
2) On build server you're passing two properties: Configuration (e.g. Release) and WebConfiguration (e.g. UATCust2)
3) This task is only run on build server, as it is part of bigger build script: developers are always working with default Debug/Release configuration, target platform configurations can be stored separately, e.g. in protected section in repository, or even on network share.

Upvotes: 1

Related Questions