If you’re building a web app or web site project using an automated MSDeploy script, in addition to binaries, you want your content and config files also published to the output folder. On the desktop, this is done by using Visual Studio’s Publish wizard. After two days of searching the web, here’s how I solved this:
<MSBuild Projects="$(teamcity_build_checkoutDir)\XXXSource\xxxServices.sln" Properties="Platform=$(Platform);Configuration=$(Configuration); DeployOnBuild=true; DeployTarget=Package; PackageLocation=$(teamcity_build_checkoutDir)\Output\$(Configuration); PackageAsSingleFile=False; AutoParameterizationWebConfigConnectionStrings=False">
As you can see, I’m using MSBuild, specifying the platform and configuration. The Publish part is done by setting DeployOnBuild and DeployTarget properties, and specifying PackageLocation. Other parameters are specific to my situation so you may not want to set them (read on for more details).
Basically, this solution uses new VS2010/.NET 4.0 WebDeploy-based publishing methodology, you can read more about it here and here. The first link describes generating WebDeploy package via MsBuild script. The second link describes using DeployOnBuild parameter to deploy the package to the web server as part of the normal build process (as opposed to invoking MsBuild second time, as described in the first post).
In my case, I don’t want to deploy the package right away, but I do want to build the package as part of my normal build process. The novelty part in my solution is combining the DeployOnBuild approach with the Package target to get the best of both worlds.
Now, regarding other parameters, PackageAsSingleFile=false indicates that the package content should not be compressed to a zip-file (you can also set this directly in your web project’s Package/Publish properties). This is useful to me because I don’t intend to actually install these using WebDeploy, all I need is a set of binaries/content/config I can take and deploy onto my servers.
The last parameter (AutoParameterizationWebConfigConnectionStrings) is used to disable auto-parameterization. I need this since my script updates Web.Config with environment-specific settings in between the multiple configurations being built. So if I don’t disable auto-parametrization, the web.config file will be locked, and I won’t be able to write to it. Here’s the error I was getting before I disabled auto-parametrization:
error MSB3021: Unable to copy file "C:\BuildAgent\work\WebService\web.config_build" to "C:\BuildAgent\work\WebService\web.config". The process cannot access the file 'C:\BuildAgent\work\WebService\web.config' because it is being used by another process.