WebDeploy and MSBUILD - Build all web deployment packages in solution file

Posted : Tuesday, 08 October 2013 21:22:00

Web Deploy(and MSBUILD :-)), we all love them right?

I am currently working a project where in a multi application solution, the complexity of the vision means we have to be on top of deployment. I have blogged about WebDeploy before but its sooooo good I thought I’d do it again when I found this latest gem. We’re currently using TeamCity for Continuous Integration and Continuous Deployment. Its great and makes QA and code management a doddle so any deployment related stuff needs to be reachable from TeamCity.

We have seen build times increase over 12 months since I have been involved in the project so looking to separate out build tasks in order to share compiled assemblies between test and deployment (and patching) scenarios. We wanted to build all the Web Deploy packages from a solution file so all the build output can be created as artifacts for subsequent build steps – I could only find how to do it from a project file. Including the deployment packages in the solution build output and artifact tree as outlined means that a unit tested build can be deployed as soon as tests pass – hey you’ve got to stay close to deployed code right?…discuss ;-)

So after a bit of google-and-binging I came to the man himself Sayed Ibrahim Hashimi....


Sayed outlines an approach which uses conditional build properties in the .csproj(or .vbproj I guess)…

1213   <PropertyGroup>

1214     <DeployOnBuild Condition=" '$(BuildPackages)'!='' ">$(BuildPackages)</DeployOnBuild>

1215     <DesktopBuildPackageLocation Condition=" '$(BuildPackages)'!='' ">$(DeployPackageLocation)\$(AssemblyName)\$(AssemblyName).zip</DesktopBuildPackageLocation>

1216   </PropertyGroup>

The adaptation I used was to only define the DeployOnBuild  and DesktopBuildPackageLocation  build properties  if the BuildPackages property is set to true – I do this via the either the command line if running locally or a TeamCity system parameter which automatically get mapped to MSBUILD properties.  I also supply the build parameter DeployPackageLocation to specify each project file package output location – this is then added as an artifact path on TeamCity.

I had some unpredictable behavior trying this out when I used some other common Web Deploy switches (DeployTarget and CreatePackageOnPublish) under certain combinations MSBUILD will try to deploy the package - we want to create an artifact for subsequent build steps that can be transformed for different environments at a later point to.

I had issues using relative paths as the DeployPackageLocation but it works fine as an absolute one.

There we go. All we need to do to include any website applications in the build is to add them to the solution and then add to the project file, the PropertyGroup defined above before the lines that start as below….

1217   <Import Project="$.....

To run this from the command line it's a simple matter of something like below...

> MSBUILD <SolutionPath>.sln /P:Configuration=Release /P:Platform="Any CPU" /P:BuildPackages=true /P:DeployPackageLocation="<YourOutputLocation>"

...and you get a lovely set of deployment packages that you can point at a web deploy endpoint, fix the emergency, and get back to work :-) Good work MSBUILD-guys, and OK "DeployOnBuild" makes sense but "DesktopBuildPackageLocation"??? Whats that about? can I submit a patch to call it DeployPackageLocation?

  • (This will not appear on the site)