TeamCity Setup for Web API Application

Overview

I was recently tasked with setting up a continuous integration build on a development server for a Visual Studio 2015 Web API solution. I had a little experience using Jenkins but had never attempted to set up such an application. But it was just a single application deploying to the same server. How hard could that be? I quickly found out. In all of my web searches I found maybe a couple of end to end articles but they proved to be incomplete and applied to older versions of TeamCity. The TeamCity documentation is very though but I still struggled with my limited DevOps experience. I can count only a few times I had ever even used MsBuild in my decades of Microsoft experience.

Jet Brains describes TeamCity as “Powerful Continuous Integration out of the box”. The latest version is 10.0 and the hefty 900 MB plus Windows installer may be downloaded here. The Professional version is free and offers the use of up to three build agents (MsBuild, script, NuGet, etc.) and twenty build configurations.

Installation

The installation is pretty straightforward and there were no problems. Be aware that the installer might put the current Windows user account in a Windows reporting user group. I could not determine if TeamCity was responsible for this and we removed the account from the group since we received a security alert about this. TeamCity seems to operate just fine without this group membership.

You will need to create a database for the system to use. We created an empty “TeamCity” database in SQL Server. You will be prompted to enter the connection information along with a SQL account and password. For SQL Server the JDBC drivers must be installed on the server. The JDBC driver package gives you two versions. You will have to tell TeamCity which one to use. I found the 6.0 version had no problems. MySQL and other databases are supported as well.

Important File Locations

With any such large complex application files are created and stored in various places. Here are some of the important locations for our installation. Note that you will specify the TeamCity Installation location during the install:

Name Description
TeamCity Installation E:\TeamCity
Application Data C:\ProgramData\JetBrains\TeamCity
Repository Location E:\TeamCity\buildAgent\work\{generated Id}\
The source, libraries, and compiled files for the project will be here.
NuGet packages folder will be created and loaded at the level of the solution file if you use a NuGet agent in TeamCity.
Windows 10 SDK Installer at https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
This would not install on our server so I copied the files on the next line from my dev machine to same folder on the server.
SDK Files For MsBuild version 14 this will be “C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\”.
JDBC Files C:\ProgramData\JetBrains\TeamCity\lib\jdbc
Copy the files in sqljdbc_6.0\enu\jre8\sqljdbc42.jar to this folder
Microsoft Build Tools 2015 Installer at https://www.microsoft.com/en-us/download/details.aspx?id=48159
Visual Studio Files C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0
Copy these files from your dev machine to the same location on the server
NuGet Executable https://dist.nuget.org/index.html

Setting up the root project

The first step is to set up your root project. On this page I only used the General Settings and VCS Roots menu items.

Under VCS Roots you create a connection to source control. This was very straightforward. You might want to create a new login for use by TeamCity. It appears it only needs read only access. Note that the Template below is not used in our setup but could be used to simplify the setup of multiple similar builds.

The Root Project

On the General tab click the Create subproject button and give it a Name, a Project Id, and a description as show in this edit view of my subproject.

After you have created your subproject click on the Create Build Configuration and give it a name. I used “Standard Build” here. When it is created you click on the edit link by the Build Configuration (WebSvcBuild here). You then get a menu for the build steps.

Sub-Project Edit View

Build Configuration

General Settings

On this page enter a build name. Here I used “StandardBuild”. TeamCity creates the Build Configuration ID for you, which can be changed. I used the defaults for the rest of the page.

General Settings

VCS Roots

Here you need to click on the Attach VCS root button to create your VCS Connection.

VCS Roots

Edit VCS Roots

Here is the edit view of the VCS root that is shown when you click the Edit link next to the VCS root name. Once again choose a name then enter the location and credentials for your VCS.

Edit VCS Root

Build Steps

Here is where the build and deploy are defined, and where I spent most of my struggles. You may use up to three build agents with the Professional version.

There is a NuGet runner you can use to retrieve your packages. The files will be placed in the packages folder at the same level of the solution. I had problems getting all my packages since we have an aggressive firewall which caused timeouts on various packages. I reverted to copying my packages from my development machine. This was just as well since I could find no way to direct the packages to our standard lib folder that is at a level above the solution. Note that you will have to copy NuGet.exe to the server and tell TeamCity where it is.

For a .Net application there is Solution runner type. I began using the Solution runner to compile my project and added a Powershell script runner to copy the compiled files to the target IIS folder. This seemed to work fine until I got a 404 for every call made to the deployed site.

Another investigation found that two key files were missing:

  • App_global.asax.compiled
  • App_global.asax.dll

These files are created when you build with a Publish profile. I could not make the Solution runner create the Publish profile so I reverted to using the MsBuild runner. I developed the build parameters and publish profiles on my dev machine before trying them in TeamCity. The publish profile is stored at

  • {solution level}\{WebApiProject}\Properties\PublishProfiles\MyServicesPublish.pubxml.

These are the MsBuild parameters that worked on my dev machine:

  • /p:DeployOnBuild=true
  • /p:PublishProfile=MyServicesPublish
  • /p:AspnetMergePath=”C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools\”

However when I used these parameters in TeamCity I got this error: “Can’t find the valid AspnetMergePath”. Thus began another two hour investigation. The merge path specified was there. After trying many things and making numerous web searches I still got this same error message.

By chance I noticed the error message had a single quote and double quote at the end in what I thought was the wrong order. I changed the double quotes to single quotes on the AspnetMergePath parameter, same error. I guess it was 1995 when Windows allowed you the luxury of spaces in file and folder names. In desperation I copied the contents to a new folder:

  • {TeamCity Install}\bin\NETFX4.6Tools.

Most any folder will do just get rid of the spaces in the last folder. Without the spaces in the path I removed the quotes from the AspnetMergePath parameter. After this my project ran without errors.

Build Steps

MsBuild Step

Here is my completed MsBuild page. Note that the Build file path is always relative to your root source control folder. The Targets has Rebuild and Publish to ensure App_Global files are created. My Publish profile file has the path to my IIS folder. This eliminates having a script runner that copies files from the VCS location and saves you from using one of your three runners.

MsBuild Step

Triggers

You add a trigger for the build here with the Add new trigger button.

Triggers

Edit VCS Trigger

This is the edit view of the trigger configuration which builds the system whenever there is a check-in.

Edit VCS Trigger

Agent Requirements

I did not have to change anything on Agent Requirements but wanted to point out that you can check here to see that MS Build Tools are installed correctly. Here its condition is “exists”.

Agent Requirements