Apr
27
2009

TeamCity #1: Creating an MSBuild File and talks on Continuous Integration

Round #1: Setting things up

Now, TeamCity is unbelievably simply to set up. No I really mean it! Just watch Rob Conery tell it like it is… Or even more detail with Sebastien Lachance… My point here is, I am not going to reinvent the wheel. There have been several blog posts, video’s and tutorials put together to show you how to do it. Where I want to come in is at the point of external tools that perform code analysis, unit testing, etc to allow you to gain better insight and attain a higher level of accountability over our code…

Starting at MSBuild…

MSBuild allows you to compile your code without the use of an IDE like Visual Studio. It is basically a build platform utility executed from the command line within the .NET Framework. Now, MSBuild can be used purely at the command line using arguments/ switches but its true power comes from an external XML file based on a well-defined XML schema which you can create to perform several tasks.

The build file is made up of the following, and as you’ll find, acts much like a class;

ItemGroups – These are basically user defined collections of, well, fields like in a class. The Include attribute specifies the field value.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
  <ItemGroup>
    <Compile Include="Customer.cs"></Compile>
    <Compile Include="Order.cs"></Compile>
  </ItemGroup>
 
  <Target Name="BuildSolution">
    <MSBuild Targets="Rebuild"
             Properties="Configuration=Release;Platform=Any CPU">
      <Csc Sources="$(Compile)"></Csc>
    </MSBuild>           
  </Target>
</Project>

Within the build file you can use these collection items in task inputs/ parameters which can clean things up very nicely, and organized.

Properties - Key/value pairs that can be used to configure builds. Properties are useful similar to ItemGroup collections in that you can use them throughout the build file to clean things up… A little code reuse if you will.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
  <PropertyGroup>
    <ProjectToBuild Include="$(MSBuildProjectDirectory)\Lulu.sln"></ProjectToBuild>
  </PropertyGroup>
 
  <Target Name="RebuildSolution">
    <MSBuild Projects="$(ProjectToBuild)"
             Targets="Rebuild"
             Properties="Configuration=$(Configuration);Platform=Any CPU"/>
  </Target>
</Project>

Tasks - A unit of executable code used by MSBuild to perform procedures within the build. A Task is nested within a Target, and a target can consist of one or more Tasks as stated above. Below we see an example of a Target consisting of a built in MSBuild task called Copy, which will do what its name implies.

<Target Name="CopyFilesToStage">
    <Copy
        SourceFiles="@(SourceFiles)"
        DestinationFolder="@(StageFolder)">
        <Output
            TaskParameter="CopiedFiles"
            ItemName="SuccessfullyCopiedFiles"/>
     </Copy>
</Target>

Targets - Groups Tasks together in a particular order and allow sections of the build process to be called from the command line. The Targets allow you to organize tasks into more logical groups.

Solutions with CI ‘Stands Alone’!!!

On the DMZ in South Korea there is a US Army camp called Camp Greaves where the 1st Battalion, 506th Infantry is stationed. It is stationed, well, on the DMZ and is quite the lonely place… There is a small one way bridge called the Freedom Bridge that is heavily fortified, wired with explosives to blow, and maintained by the 1/506th. They are there in case all hell breaks loose. The yell ‘Stands Alone’ and solute each time a vehicle crosses the bridge. A buddy of mine used to always reply, ‘Sleeps Together’ when we crossed, but that is another story all in itself… They are completely prepared to be isolated and operate on their own. This, in my opinion, is the epitome of a proper CI solution. They need nothing!They have all they need to operate on their own! 

To me, one of the most important things about successful Continuous Integration is the ability for any developer to walk into the project at any give point and be able to work… What I mean by that is they can;

  1. Check out the solution from source control
  2. Perform a successful build with all whistles and bells…

This means that any and all dependencies that the build has are included within the source, external build and analysis tools included! There should be no need to download and install any third party tools whatsoever.

Think about your solution. All dependencies are referenced and included within the solution file under the Visual Studio umbrella. When it comes to Continuous Integration, think on a broader scope, think outside of the Visual Studio box, think about the build in all its entirety. Test harness exe’s/ dlls, code analysis exe’s/ dll’s, and any other items needed to perform the build!

One of the things I have learned from Jay Flowers and his CI Factory endeavors (great CI solution by the way, love it) is organization in this arena. I do love the directory structure that he has put together; I follow it and strongly recommend it. Here is an example for the “Lulu” solution;

Folder_Structure

Here you can see the structure I am talking about. The directory tree is fairly straight forward. Starting at the Trunk folder, this enables you to house “branches” as well, you have three primary directories;

  • Build - This folder contains all external packages to include any code analysis tools, and your build artifacts. Your build file can also live here.
  • Product - Here we store your solution file and two sub directories;
    • Production - Your solution projects in their own sub directory.
    • Unit Tests – With each Test project also in their own sub directories.
  • Third Party - Here, all external solution dependencies are stored to include third party components that your solution depends on and unit testing dll's.
    In essence, what this structure does for me is give a clear and organized structure to all that is solution, build tools included… Now, granted, this may put extra weight on our repository, maybe 10MB and even more in some instance depending on our external code analysis tools, yet we can achieve our goal of checking the solution out of source control and being able to perform, a proper build!

Jay Flowers, as I stated earlier, is responsible for my adoption of this model. This is the primary model of CI Factory I do, however, would like to point out that it may even be from Mr.CI himself Martin Fowler, better put the God of CI, but for now I am going to go ahead and give props to Jay.

Back to the build file…

As I stated, before I digressed slightly, MSBuild is based on a well defined XML schema. The code required to compile your project can be very straight forward. Here is a brief example;

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 
  <ItemGroup>
    <ProjectToBuild Include="$(MSBuildProjectDirectory)\Lulu.sln"></ProjectToBuild>
  </ItemGroup>
 
  <Target Name="BuildSolution">
    <MSBuild Projects="@(ProjectToBuild)"
             Targets="Rebuild"
             Properties="Configuration=Release;Platform=Any CPU"/>           
  </Target>
</Project>

The Parent/ Root tag is the Project tag. There are a few attributes here worth pointing out. Walking through this code, the first thing that should be noted is the xml namespace reference. Comes in very handy when working in Visual Studio to get intellisense operating on your MSBuild file.

Additionally, the ToolsVersion attribute specifies what version of the .NET Framework to build your solution under.

Full Circle, Back to TeamCity

Hopefully I have given a decent enough overview of the basics of MSBuild to get you up to speed to continue along back to TeamCity. From here, TeamCity makes it simple. The Build Runner page of your Build Configuration select MSBuild;

BuildRunner

Set the Build File Path to the location of your build file. This is in respects to your source control root directory. As we discussed earlier, our root is the Trunk folder and, in this instance, the build file is located in our Product folder. Everything else is straight forward here, you are not required to fill out any additional info.

There are some interesting items of great value here which I will dive into in the next post of the series. JetBrains documentation is pretty string here and I recommend checking it out.

Once we configure the create our MSBuild file and configure the Build Runner, we are in business. At this point we should see a nice build report for the project with a successful build.

BuildSummary

 

 

 

More to come, enjoy!

You can download the demo for this series here;

Download Lulu CI Demo Solution

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

About me...

I am a software dev specializing in web based application lovin life in So Cal!

Month List