views:

693

answers:

3

Visual Studio 2010 has a Publish command that allows you to publish your Web Application Project to a file system location. I'd like to do this on my TeamCity build server, so I need to do it with the solution runner or msbuild. I tried using the Publish target, but I think that might be for ClickOnce:

msbuild Project.csproj /t:Publish /p:Configuration=Deploy

I basically want to do exactly what a web deployment project does, but without the add-in. I need it to compile the WAP, remove any files unnecessary for execution, perform any web.config transformations, and copy the output to a specified location.

My Solution, based on Jeff Siver's answer

<Target Name="Deploy">
    <MSBuild Projects="$(SolutionFile)" 
             Properties="Configuration=$(Configuration);DeployOnBuild=true;DeployTarget=Package" 
             ContinueOnError="false" />
    <Exec Command="&quot;$(ProjectPath)\obj\$(Configuration)\Package\$(ProjectName).deploy.cmd&quot; /y /m:$(DeployServer) -enableRule:DoNotDeleteRule" 
          ContinueOnError="false" />
</Target>
A: 

There are a lot of ways to accomplish what you are going after. You could just use XCopy in your MSBuild file to copy the build to where it needs deployed.

runxc1 Bret Ferrier
But how do I initiate a build that includes web.config transformations? Once I get that figured out then I could use the MSBuild copy command.
jrummell
A: 

I got it mostly working without a custom msbuild script. Here are the relevant TeamCity build configuration settings:

Artifact paths: %system.teamcity.build.workingDir%\MyProject\obj\Debug\Package\PackageTmp 
Type of runner: MSBuild (Runner for MSBuild files) 
Build file path: MyProject\MyProject.csproj 
Working directory: same as checkout directory 
MSBuild version: Microsoft .NET Framework 4.0 
MSBuild ToolsVersion: 4.0 
Run platform: x86 
Targets: Package 
Command line parameters to MSBuild.exe: /p:Configuration=Debug

This will compile, package (with web.config transformation), and save the output as artifacts. The only thing missing is copying the output to a specified location, but that could be done either in another TeamCity build configuration with an artifact dependency or with an msbuild script.

Update

Here is an msbuild script that will compile, package (with web.config transformation), and copy the output to my staging server

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
        <SolutionName>MySolution</SolutionName>
        <SolutionFile>$(SolutionName).sln</SolutionFile>
        <ProjectName>MyProject</ProjectName>
        <ProjectFile>$(ProjectName)\$(ProjectName).csproj</ProjectFile>
    </PropertyGroup>

    <Target Name="Build" DependsOnTargets="BuildPackage;CopyOutput" />

    <Target Name="BuildPackage">
        <MSBuild Projects="$(SolutionFile)" ContinueOnError="false" Targets="Rebuild" Properties="Configuration=$(Configuration)" />
        <MSBuild Projects="$(ProjectFile)" ContinueOnError="false" Targets="Package" Properties="Configuration=$(Configuration)" />
    </Target>

    <Target Name="CopyOutput">
        <ItemGroup>
            <PackagedFiles Include="$(ProjectName)\obj\$(Configuration)\Package\PackageTmp\**\*.*"/>
        </ItemGroup>
        <Copy SourceFiles="@(PackagedFiles)" DestinationFiles="@(PackagedFiles->'\\build02\wwwroot\$(ProjectName)\$(Configuration)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    </Target>
</Project>

You can also remove the SolutionName and ProjectName properties from the PropertyGroup tag and pass them to msbuild.

msbuild build.xml /p:Configuration=Deploy;SolutionName=MySolution;ProjectName=MyProject
jrummell
This is a great solution, I've just used this with an MSDeploy command as an exec task in the CopyOutput target. Thanks!
Troy Hunt
+2  A: 

I don't know TeamCity so I hope this can work for you.

The best way I've found to do this is with MSDeploy.exe. This is part of the WebDeploy project run by Microsoft. You can download the bits here.

With WebDeploy, you run the command line

msdeploy.exe -verb:sync -source:contentPath=c:\webApp -dest:contentPath=c:\DeployedWebApp

This does the same thing as the VS Publish command, copying only the necessary bits to the deployment folder.

Jeff Siver
That looks promising. However, it looks like the Management Service is only available on Server 2008. My staging server (where I want to automate deployment) is running Windows 7 Pro.
jrummell
There are two pieces to the product. The pieces that integrate right into IIS require Server 2008. The command line component does not have that requirement; I have it running on a Server 2003 box I use for deployments.
Jeff Siver
I've done some reading on MSDeploy. I got it installed and working on my staging server, thanks! Can I run MSDeploy from an MSBuild script?
jrummell
It should run fine as an EXEC task in your build script.
Jeff Siver