Working on centralizing configurations, app settings and connection strings, for multiple solutions, while also switching over to use msdeploy from command line to deploy we
I can elaborate a bit on options #1/#3 and compare them. The previous reply was not accurate in stating that you have to build multiple times with PackageWeb, you only need to build once.
In this approach you will create a parameters.xml file in your web project which will declare additional Web Deploy parameters.
When you build the Web Deploy package the parameters declared in parameters.xml are created in the package. When this web deploy package is created the web.config file will be transformed based on the build config (and now potentially a profile specific transform as well).
You can use that package and a setparameters.xml to publish the package specifying the Web Deploy parameter values. You can create different setparameters.xml files and use that along with the same package to publish to multiple destinations. To publish using this technique you can use either the deploy.cmd which VS generates or call msdeploy.exe with the correct set of parameters.
PackageWeb extends the package process so that when you create a Web Deploy package the web.config transforms are included in the package as well as an assembly which can execute the transforms.
In addition to this when you create a web deploy package a publish-interactive.ps1 file is generated. You can use this file to publish your package. It will prompt you for; the web.config transform to be applied, the web deploy parameter values, and the web deploy endpoint info itself. When you run through a publish the values you gave are saved to publish-configuration.ps1.readme
. You can remove the .readme and publish-interactive.ps1 will use the values from that file to automate the publish. You can also specify the file to be used for settings.
If you created a parameters.xml file when the web deploy package is created by VS it will result in web deploy parameters being included in the package. PackageWeb will pick those up and prompt you for those as well.
So what are the differences between these approaches?
With Option #1 the web.config which gets into the package is already transformed. You will not have an opportunity to transform the file again. With both approaches you can specify web deploy parameter values though so that may suit your needs. If you are modifying big chunks of XML from one env to the other then the web.config transforms may be beneficial. So PackageWeb may be a better choice.
With Option #1 you have to manually create the SetParameters.xml file. With PackageWeb you can run through the process using the WhatIf option. You will be prompted for the values and it will create the settings file for you.
You can easily automate both approaches. PackageWeb essentially builds on the parameters.xml/setparameters.xml technique and offers a super-set of the functionality.
If you want to keep things as simple as possible with the least # of moving parts I would recommend option #1, because you can directly call msdeploy.exe if needed.
If you want to simplify automating the publish and you prefer PowerShell to a standard command prompt then try out PackageWeb.
I have a 5 minute video on PackageWeb at http://sedodream.com/2012/03/14/PackageWebUpdatedAndVideoBelow.aspx. If you are publishing web deploy packages I encourage you guys to try it out. If it doesn't meet your needs please let me know because we may use what we learn in PackageWeb later in a more formal way.
I ended up solving this problem with a combination of msbuild running on TeamCity to create NuGet packages which can be consumed by OctopusDeploy.
Octopus allow for an application packaged up into a nuget package (built once) to be pushed through multiple environments. Config can be transformed on a per environment or even a per machine basis using standard ms transforms. Links to relevent Octopus docs below.
Packaging for Octopus
Configuring config transforms
We use option #1 and it works out well enough. We deploy to about 30-40 sites and applications using this approach.
I think option #2 will cause headaches for either you or the developers. You'll either have to make sure the sections with settings are removed from the config on deployment, or lock them on the server so that the local config can't add them.
For option #3 you will have to do multiple builds to get the transformed config files. It also isn't very feasible if you have a large number of sites to deploy.
Option #4 could work, but you might run into limitations here. It's either the whole section is in a separate file or its all in the main file so there's no in-between.
Option #5 looks interesting, but I haven't used it so I can't say much about it.
We use #5 and it works very well. Using MSBuild for publish profiles provides a bunch of flexibility (Items are particularly useful).
In our deployment pipeline, only the website package, build/beployment targets and publish profiles are made available to deployment stages. Source code, including project files, are only utilised by the build/test stage.
FYI, we went with publish profiles specifically as you'll quickly run into the problem of keeping environment specific server details / credentials, skip clauses and parameter values together. WPP / Publish Profiles track all these things in the pubxml
file, and MSBuild's features allow for some nice convention-over-configuration "helpers" for common-but-"noisy" tasks.