In part two of my MSBuild tutorial I needed to find a way to call Visual Studio’s Publish Web Site feature from MSBuild. Much trawling of the interweb failed to find anything of use, so in the end I had to produce my own target which copied the relevant files into the output folder.
The problem with this approach is that it only works for files of type dll, aspx or config. It is a simple task to add an extension, for example png, however on larger projects this becomes impractical. Developers would have to check the build script each time they added or removed a file just in case the Publish target needed to be updated. These are just the sort of jobs that get forgotten, which can lead to invalid builds later on.
Fortunately I came across a post on Mirosław Jedkynak’s blog showing how to use MSBuild to publish a web site. As some of you may be aware, a project file (vbproj or, in the case of my demo, csproj) contains targets of its own, as well as importing targets from other files that come as part of a Visual Studio installation. One such file is Microsoft.WebApplication.targets. This file provides the _CopyWebApplication target which will effectively replace my home-brewed Publish target.
In order to make use of this target we need to pass it two properties, WebProjectOutputDir and OutDir, which will ensure that the files get published into the correct folder. Here is an example
<Target Name="Publish"> <RemoveDir Directories="$(OutputFolder)" ContinueOnError="true" /> <MSBuild Projects="BuildDemoSite.csproj" Targets="ResolveReferences;_CopyWebApplication" Properties="WebProjectOutputDir=$(OutputFolder); OutDir=$(WebProjectOutputDir)\" /> </Target>
As you can see the ResolveReferences target is also called, this ensures that any third party dependencies are copied over as well.
Integrating this into my demo build script was simple, however I noticed that some files were being copied over that I didn’t want. These were the build script itself, and the environment-specific config files. This is because their build action was set to Content. Once I had switched it to None and ran the script again, everything was fine. The build action can be set by right-clicking on a file in the Solution Explorer and selecting Properties. Build Action is the first item in the list.
I have posted a new version of the build script to CodePlex for those interested in taking a look.