Monday, May 6, 2013

How to Automate App Deployment in TeamCity (Part 3)

Please notice that this is a multi-part, step-by-step guide, on how to automate application deployment in TeamCity CI Server. Links to Part 1 here and Part 2 here

Part 3: Completing the Web Deploy Configuration

We now have our TeamCity deployment step configured in our CI Build project, and our website configuration created and working on IIS. However, the current files being deployed are not the right ones. We need to modify our existing project’s build script to add the required steps, which include web packaging, clean up, and deployment.

Here’s the steps you need to add to the script:

  1: <!-- Packages and copies the web application files required by a web publishing step -->
  2: <Target Name="DeployWeb" DependsOnTargets="DeleteBinFiles;Package;CopyWeb;CopyConfigs" />
  3:   
  4: <!-- Deletes all previous files from directory -->
  5: <Target Name="DeleteBinFiles">
  6:     <Message Text="Deleting bin files from $(DestinationPath)" />
  7:     <ItemGroup>
  8:   <FilesToDelete Include="$(DestinationPath)\**\*.*"/>
  9:     </ItemGroup>
 10:     <Delete Files="@(FilesToDelete)" />
 11: </Target>
 12:   
 13: <Target Name="Package">
 14:     <Message Text="Packaging project..." />
 15:     <MSBuild Projects="$(ProjectFile)" ContinueOnError="false" Targets="Package" Properties="Configuration=$(Configuration)" />
 16: </Target>
 17:  
 18: <Target Name="CopyWeb">
 19:     <Message Text="Copying project files from" />
 20:     <ItemGroup>
 21:   <PackagedFiles Include="$(PackagedProjectDir)\**\*.*"/>
 22:     </ItemGroup>
 23:     <Copy SourceFiles="@(PackagedFiles)" DestinationFolder="$(DestinationPath)\%(RecursiveDir)"/>
 24: </Target>
 25:   
 26: <Target Name="CopyConfigs">
 27:     <Message Text="Copying configuration files from $(PackagedProjectWebConfigDir) to $(DestinationPath)..." />
 28:     <ItemGroup>
 29:   <ConfigFiles Include="$(PackagedProjectWebConfigDir)\**\*.*"/>
 30:     </ItemGroup>
 31:     <Copy SourceFiles="@(ConfigFiles)" DestinationFolder="$(DestinationPath)\%(RecursiveDir)"/>
 32: </Target>

Before committing the changes, just make sure to go to TeamCity and modify the Target setting of the deploy step so it matches our “DeployWeb” target, instead of the “DeployApp” we entered before. Commit the build script changes and let’s see how it goes.


TC_webdeploy_34


Now when I committed this the first time, I got errors on the Build process referring to the target “Package” not being found. Banged my head against the wall several times while trying to figure out the issue. I even started to play around with parameters for the MSBuild command line options, without success.

First, in VS2012 the package/deploy settings have changed. Now you need to create a publish package and enter the packaging details you want. Then you need to update the build script to introduce the new parameters. That done, I went ahead to create the package using MSBuild from the command line, which is what TeamCity will do behind the scenes.

TC_webdeploy_42

Then, I got the same error from the command line. Many suggest is a .NET framework issue, or the lack of having MSDeploy installed correctly, however, I’m sure that my development machine has the required tools and correct configuration.

It turns out, that the problem is trying to compile the entire solution, instead of just the web site project. Check this helpful article about this kind of issue.

Working Local command (from the app project directory):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MvcApplication2.csproj /t:Package /p:PublishProfile=Package /p:Configuration=Release

TC_webdeploy_43
Now, this worked locally, but unfortunately, I was getting the same error on the server. So now is time to make sure that the web deploy agent for VS2012 projects is actually installed on the server.

TC_webdeploy_44

Finally, I figure out that the problem was that the required WebApp deploy targets were not available.

In one of the first related articles of the TeamCity series, we copied the webApplications folder from Visual Studio 11 but not the Web folder.

The solution is to copy the following folders to your server:
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications

Working Server side command:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe MvcApplication2.csproj /t:Package /p:PublishProfile=Package /p:Configuration=Release

TC_webdeploy_53
With the web deployment process now working, you can go ahead and run the entire Build process from TeamCity.

The Build Workflow should be successful and do the following:


1. Retrieve latest changes from source control repo.
2. Compile the entire solution, including unit test project.
3. Run the entire unit test suite.
4. Package and deploy the web application files into the IIS corresponding directory.


TeamCity Build Reports:

TC_webdeploy_45

TC_webdeploy_46


Compiled and Packaged Files:

TC_webdeploy_47

TC_webdeploy_48
TC_webdeploy_49
Deployed Files:

TC_webdeploy_50
Verifying site in IIS:

TC_webdeploy_51
Running Web App:

TC_webdeploy_52
There you go. We have completed a full continuous integration and continuous deployment setup on a Windows Server machine with TeamCity and IIS for an ASP.NET MVC 4.0 application.

I really hope this complete, detailed, step-by-step guide helps you as much as possible. Feel free to share your comments, issues, contributions or corrections.

You can download the complete MVC sample application, including the build script from my Github repo here.

Here you can find some helpful articles with related topics:

Web.config Transformation Using TeamCity
MSBuild and Deployable Packages

No comments:

Post a Comment