My blog has moved!

Visit http://www.codeprogression.com or http://www.elegantcode.com/about/richard-cirerol and update your bookmarks.

Sunday, May 24, 2009

Implementing TeamCity for .NET Projects, Part 4: Using Build Scripts

For more information on this series, please see the introductory post. This post also assumes that you have completed parts 1-3. The sample solution has been updated with new build scripts as of May 24, 2009. If you have downloaded the solution previously, please download the updated solution. You can explore the source or create a working copy. A zip file has been provided for you to download to import into your own writeable repository.

For more advanced or complex build scenarios, the build it solution runners prove somewhat inflexible. Once you have arrived at this conclusion, you will most likely start investigating some of the other build runner options.

For .NET projects, the two obvious choices are MSBuild and NAnt. The new hotness for building .NET projects is Rake. And, if you use a scripting language not built into TeamCity (such as FinalBuilder, Psake, or shell scripts), the command line runner is your friend. TeamCity also has two .NET build runners specifically targeting code inspection: Duplicates finder and FxCop.

I have been using NAnt for several years to build both web and desktop applications. NAnt has been fairly quiet for the last couple years. The latest official release (0.86 Beta 1) is dated December 2007, but there has been sporadic 0.86 Beta 2 activity in the nightly releases.

I have just started working with Rake for build scripts. (A big thanks to the Fluent NHibernate and FubuMVC contributors for their pioneering efforts on this front.) Rake, like Ruby itself, seems to be infinitely extensible.

What Should a Build Script Do?

My build scripts need to at least handle the following targets/tasks:

  1. Compile the application
  2. Run the tests
  3. Provide a code coverage report
  4. Zip up the compiled application for artifact retention
  5. Update the configuration files
  6. Publish the website to a folder or IIS virtual directory
    TeamCity natively handles 1 and 2, but we will be duplicating that functionality with the build scripts. TeamCity also allows you to download your artifacts as a zip file, but does not store it as one. TeamCity does not provide code coverage for .NET projects. However, it does for Java projects.)
    Our NAnt and Rake scripts will handle the all the tasks. I will cover the first four tasks in this post. I will cover the other three in another post.

Setting Up an NAnt Build Runner

We’ll start with an NAnt Build Runner. In your TeamCity website:

  • From the Projects page, click the drop arrow next to the existing project and click on Edit Settings
  • On the right hand side of the screen, click on the Copy button to copy the configuration
  • Name the new build configuration “Just Build It! (with NAnt)”
  • Select the Runner link from the navigation bar on the right

Based on the sample solution, enter the following values and save your changes. Leave all other values at their defaults. (If your solution is structured differently, adjust accordingly.)

Build Runner: NAnt
Path to a build file: nant.build
NAnt Home: lib/nant

Leaving the Targets text box blank will force the runner to use the default target.

The default targets in thee script files create a zipped file of the website and code coverage results from the free NCover Community edition. I am using a couple custom tasks from kiwidude for integrating NCover with the NAnt script.

In the General Settings page, add the following to the Artifacts text box to force both files to show up as artifacts:

results/Artifacts.zip
results/CoverageReport.html=>ncover

Creating custom tabs is fairly simple as well. Add the following entry to the <TeamCity data directory>/config/main-config.xml (the default data directory is named .BuildServer to create a tab that shows the NCover results for each build:

<report-tab title="NCover"
basePath="ncover"
startPage="CoverageReport.html" />

(Thanks to Laurent Kempé for the instructions on integrating NCover with TeamCity)

Setting Up a Rake Build Runner

Make another copy of a configuration and name the new build configuration “Just Build It! (with Rake)”. This time select Rake as the build runner on the Build Runner page. Leave all other values at their default. (The Rakefile in the root directory will be used. I modified the rake scripts from the FubuMVC project for this solution.)

You will need Ruby and a couple of Gems to get started. Check the information in the Ruby_Not_Installed.txt file in the root directory of the sample solution.

Setting Up an MSBuild Build Runner

I actually do not have an example of an MSBuild script (because I do not have enough experience with MSBuild). Setting up the build runner is similar to the NAnt and Rake runners. If you are interested in this build runner type, check out Ryan Anderson’s posts. He has done an excellent job detailing the process.



Upcoming posts:

  • Deployment: Using TeamCity and build scripts to update different deployment environments.

  • Setting up notifications: We will look at the different options for notifications, such as email and the tray notifier.


JetBrains TeamCity
Sample Project on GoogleCode
NAnt
NAntContrib
NCoverExplorer Downloads
NAnt
NAntContrib
NCoverExplorer Download Page (with NAnt/MSBuild documentation links)
Ruby Downloads

11 comments:

t800t8 said...

Hi,

When I run the build (with NAnt), the log file contains an error "External Program Failed: C:\TeamCity\buildAgent\work\4c319feb70f6b727\lib\ncover\NCover.Console.exe (return code was 1)".

Do I need to setup anything for NCover?

Regards

Richard said...

@t8oot8,

You do not need to install anything. The NAnt build runs two sets of tests through NCover/NUnit. My hunch is that the first set (AdventureMVC.Tests) runs fine and the second set (AdventureMVC.Data.FluentNHibernate.Tests) fails.

Make sure that you have the AdventureWorks database installed and that src/AdventureMVC/Web.config and src/AdventureMVC.Data.FluentNHibernate.Tests/App.config are updated with the correct connection string values for your environment.

If this is not the case, please let me know.

-Richard

t800t8 said...

Richard,

I checked again, all the tests passed (as in part 3 of this series), but same problem. Here is NAnt output:

NAnt output: [ncover] Coverage Log: coverage.log [ncover] [ncover] Waiting for profiled application to connect...NUnit version 2.4.8 [ncover] Copyright (C) 2002-2007 Charlie Poole. [ncover] Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov. [ncover] Copyright (C) 2000-2002 Philip Craig. [ncover] All Rights Reserved. [ncover] [ncover] Runtime Environment - [ncover] OS Version: Microsoft Windows NT 6.1.7100.0 [ncover] CLR Version: 2.0.50727.4918 ( Net 2.0.50727.4918 ) [ncover] [ncover] TeamCity addin initializing... [ncover] TeamCity addin loaded [ncover] TeamCity addin installed [ncover] . [ncover] Tests run: 1, Failures: 0, Not run: 0, Time: 0.138 seconds [ncover] [ncover] [ncover] Connected [ncover] Profiled process terminated. Profiler connection not established. [ncover] Deleting settings file: C:\TeamCity\BuildAgent\temp\buildTmp\tmpB237.tmp.ncoversettings BUILD FAILED - 0 non-fatal error(s), 3 warning(s) C:\TeamCity\BuildAgent\work\d89077413084c24\nant.build(119,6): External Program Failed: C:\TeamCity\BuildAgent\work\d89077413084c24\lib\ncover\NCover.Console.exe (return code was 1) Total time: 69.9 seconds.

And do I need to create database for ApplicationServices? I'm using SQL Server 2005 Developer.

t800t8 said...

Ah, which version of Windows are you using? x86 or x64? I'm using x64. Maybe it's the problem.

Richard said...

@t8oot8,

I am using x64. NCoverExplorer registers CoverLib.dll before running coverage and unregisters it after. Unfortunately, because of this, the service account for TeamCity must be an Administrator account to run regsvr32.exe. Could this be the issue on your system?

t800t8 said...

Richard,

I tested on Win XP Pro x86 and the problem still remains.

When I install TeamCity (v4.5.1), I select the default option (Use SYSTEM account) to run the service. How about your configuration?

Richard said...

Once again, sorry for all your trouble.

I am running under the SYSTEM account as well. Do you happen to have another version of NCover or NUnit actually installed on your system? I am wondering if there is a conflict.

Also, have you tried running NAnt in your working directory? From the root folder, run "lib\NAnt\NAnt.exe"

You can also just run the unit tests. Compile first by running "lib\NAnt\NAnt.exe compile", then run "lib\nunit\nunit-console-x86.exe src\AdventureMVC.Data.FluentNHibernate.Tests\bin\debug\AdventureMVC.Data.FluentNHibernate.Tests.dll" If the tests pass, then NCover is definitely the issue.

Would you mind sending me a copy of your full build log? You should be able to download it from the top right of the build log page. You can send it to my gmail account (rcirerol is my user name).

Thanks, Richard

t800t8 said...

Richards,

Thanks for quick answer.

Yes, I have another version of NCover installed on both systems. NUnit doesn't cause the problem while I installed another version of NUnit on one of the systems.

I tried "lib\NAnt\NAnt.exe", and the same problem happens.

I also tried as you mentioned to run the tests, all of them passed.

And I drop you an email with a full build log. Please take a look.

Thanks, t800t8

Justin said...

Did you get this resolved? I have the same problem.

Richard said...

@Justin,

The problem seemed to be a conflict between an installed version of NCover and the one being referenced by the script. If you change the build script to reference your installed version, the build should finish successfully. Hope that helps.

Richard said...

FYI...TeamCity 5 currently in EAP has .NET code coverage built in. See the Release Notes.

Post a Comment