Reputation: 476
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
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
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