Using TeamCity for ASP.NET development: MSBuild Requirements

This is the second part of a blog post series on using TeamCity continuous integration server from JetBrains for asp.net development.

Here are the links to the parts of the series:

  1. Installing/Configuring TeamCity for use with IIS
  2. MSBuild requirements for web package publishing [this post]
  3. Deploying via Web Deploy
  4. Backup (pre-deploy)

2. MSBuild requirements for web package publishing

Now that we’ve installed and configured a TeamCity server it’s now time to setup a build process that in the end will deploy an asp.net web application. We need to start with publishing it though.
note: this could in reality be any type of asp.net application (MVC, WebForms, Nancy, whatever). As long as you can use the WDPP (web deploy publishing pipeline)

Disclaimer: My examples will use Visual Studio 2012 . However many of the same concepts still apply in 2010.
In short this is what will be covered:

  1. Creating an offline web application package [this post]
  2. Deploying the web application package to the test server/s [next post]

2.1 Creating an offline web application package

Since this is .NET, building/deploying an application will “require” MSBuild so that’s what we’ll start with.
Creating an “offline” web application package is actually something that you will instruct MSBuild to accomplish during the build process of your project. It’s an extension of that pipeline so-to-say.

Let’s see how to extend the pipeline!

2.1.1 DeployOnBuild

Through a property called DeployOnBuild, which you will set to true,  you will tell the MSBuild build process to be extended to perform a deploy as well. This can be a bit confusing, deploying to means “push to server”.
You can however deploy in many different ways but the two common options are:

  1. deploy via Package (offline/file system deploy)
  2. deploy via MSDeploy (online/instant deploy)

We will focus on offline deploy (a.k.a package) since we want to push to the testing environment only if certain conditions are met and not on every single change.
The bonus is that we don’t have to re-compile the application just to push it to servers. We just pick up the created offline package and push that via web deploy (which we will see in the next article).

2.1.2 PublishProfile

Since this is VS 2012 it’s recommended to use use a publishing profile which will be created for you when you choose to “publish…” from Visual Studio. It’s basically just an xml file (MSBuild file) that MSBuild can translate properties from (among other things):

image
[source]

…such as the publish/deploy method, location of the package, if it should be a zip file etc. (if you’re familiar with web deploy providers you might see what these properties will control web deploy wise)
The file will end up in your project (under Properties/PublishProfiles) and you can check it in to source control (mine is called Package.pubxml)

image_thumb11

Then you’ll just have to tell MSBuild to use your profile via the PublishProfile MSBuild property by:

  1. name of the profile file without extension. (will be pulled from the default location, i.e. Properties/PublishProfiles)
  2. complete path to the .pubxml file

2.2 VS command-line

It’s always a best practice to use the VS command-line instead of the UI when you’re figuring out how instruct your build server (since you cannot fire up VS in a remote build scenario).
Below is the command that will:

  1. Compile our solution file in release mode [p:Configuration=Release]
  2. Extend the build to perform a publish [p:DeployOnBuild=true]
  3. Use the “Package” publish profile [p:PublishProfile=Package]

msbuild.exe  /p:PublishProfile=Package /p:DeployOnBuild=true /p:Configuration=Release

Next up it’s time to configure TeamCity to perform this.

2.3 TeamCity configuration

Now it’s time to “translate” that MSBuild command to a TeamCity build runner with properties and to see what errors might appear.
note: I’m not showing you how to create an MSBuild runner…that should be pretty self-explanatory or you’ll figure it out.

image

I’ve translated the MSBuild properties to TeamCity system properties as you can see from above.
In TeamCity it’s best practice to use build parameters instead of directly sending parameters to the build runner (TeamCity will take care of that for you). The bonus is that you can override build parameters if you need to depending in what scope you set them up.

Let’s test…

Error #1

“error MSB4019: The imported project “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets” was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.”

This error indicates that we’re missing some MSBuild resources that are needed.
There are two options that will fix this issue:

  1. Manually (on TeamCity server):
  2. Install VS 2012 Express (for web) on TeamCity server. It will install a little bit more that you need but I can live with that since all the required bits are included. [I’ll go for this option]

Error #2

“Package restore is disabled by default. To give consent, open the Visual Studio Options dialog, click on Package Manager node and check ‘Allow NuGet to download missing packages during build.’ You can also give consent by setting the environment variable ‘EnableNuGetPackageRestore’ to ‘true’.”

Since my web application uses NuGet and package restore you can run into that error on the TeamCity server. However, TeamCity supports setting environment variables pretty easy:

image_thumb5

note: this parameter might be good to set at the project level and not at the configuration level because then we don’t have to set it in every configuration we create.

Summary

In short this is what I had to do to my TeamCity server to make it work:

  1. Add some build parameters (a mix of system and environment).
    image
  2. Install VS 2012 Express for Web

Next time…deploying via Web Deploy.

, , ,

  1. #1 by Chaim Potts on April 10, 2013 - 08:23

    I am using TeamCity as a deploy server.It so ease and awesome that just with click of button, TeamCity build my solution,run unit tests and deploy my app to a server.

  2. #2 by Nate Rickard on September 10, 2013 - 01:31

    Thanks for the NuGet env variable tip! Much better than some of the older solutions I found on Stack Overflow, etc.

  3. #4 by Rakyat Betul on October 12, 2013 - 19:40

    Thanks for pointing tha I need to copy from the ‘Web’ folder…it works like charm!. I followed instruction from stackoverflow to copy from ‘WebApplication’ folder and I spent almost more than 2 days scratching my head why it isn’t deploying..

  4. #5 by Luisen on March 20, 2014 - 16:46

    I have TeamCity in a Remote Machine which do not have VS.
    That said, it makes any different ? I mean, I follow theese steps,
    but it seems to not be reading the PublishProfile I made

    • #6 by Johan Leino on April 7, 2014 - 19:48

      I somewhat hard to say what could be wrong based solely on that description but have you checked the profile (xml) into source control + have you made sure that MSBuild actually uses your profile?

    • #7 by Johan Leino on April 7, 2014 - 19:57

      Sorry….saw that you didn’t have VS installed (not even express). Then you have to copy/paste all the things that VS normally installs onto the TC server/agent…the MSBuild related stuff.

  5. #10 by George on April 9, 2014 - 02:29

    Johan, hi. Fantastic article and I can see it can take me to the right direction, but I have slight different problem / issue:
    I am still trying to configure to build using Visual Studio configuration in TeamCity:
    So, undercover questions: Does it really work? have you tried to build it? are there any issues with that from your prospective and experience? does it work with Visual Studio Express for Web?
    my issue:
    background: Same dev/build server / TFS2012 / VS Express for Web 2012 / Agent on the same machine / TeamCity can see agent and talks to it
    issue: Stating to run build – get this error: [Step 1/1] Failed to start MSBuild.exe. Index was outside the bounds of the array. System.IndexOutOfRangeException: Index was outside the bounds of the array.
    Any comments or suggestions?
    P.S. Apologies for asking question here – could not find your direct contact details. Cheers. George

    • #11 by Johan Leino on April 9, 2014 - 06:32

      Hi, thanks for the feedback and yes it does really work. It’s still pretty hard to say exacly what the problem might be but do you have access to the server/agent so you can try running msbuild from there. Does the log say where it looks for msbuild.exe? Try turning on verbose logging when you execute the build to get better info.

  6. #12 by Aref Karimi on July 5, 2016 - 07:09

    Thanks so much. I could not figure out how to collect the build artifacts until I read your post

  1. Configuring TeamCity for ASP.NET development: Part 3 | Johan Leino
  2. Configuring TeamCity for ASP.NET development: Part 4 | Johan Leino
  3. Using TeamCity for ASP.NET development: Installing on IIS | Johan Leino
  4. Using TeamCity for ASP.NET development: Deploying | Johan Leino
  5. Using TeamCity for ASP.NET development: Backup | Johan Leino

Leave a comment