Welcome to Manicprogrammer Sign in | Join | Help

Team Build 101 (Part 1 of 2)

This is article part one. For part two click here.

Today we engaged in a task (that seemed daunting at first, but proved to be just a little hard :)) that was the one to setup a team build for Continuous Integration of one of our websites.

For you guys that didn´t know, MSBuild does not currently support Website deployment out of the box. Well, I didn´t know. And another feature missing is when a check-in occurs start the build (which is the core of Continuous Integration). Lucky bastards as we are, both have already been done. One by Microsoft and the other by Notion Solutions, Inc.

What we wanted here was:

  1. Launch the Team Build on every check-in.
  2. Get the latest source code in the server.
  3. Build the website solution.
  4. Unit test the website solution.
  5. If everything goes well, zip the built website files and place it in the test site /archived folder with the zip name being: ProjectName_Major_Minor_Build_Release.zip. (this one I borrowed the idea of Douglas Rohm)
  6. If everything goes well copy all the built website files to the test site folder, so the test site always reflect the latest check-ins.
  7. I had to have a way to check the team builds for all our projects without having to look in VS 2005, in two ways:
    1. I wanted to be notified by e-mail.
    2. I wanted RSS Feeds for every team build so I can get notified by RSS Bandit.

Well, satisfying all those conditions can be tricky. So I started to look for resources that could help me. This is when I found (guided by Scott Guthrie I must admit - YES HE DID IT AGAIN, lol!) a great article, but when I say great I can´t stress it enough. The article was wrote by Douglas Rohm and presents almost the entire solution for the above requirements.

I was amazed when I finished reading...Nah, of course you know I didn´t finish reading the article before I started trying to make it work. If i did that I wouldn´t be a developer, lol.

As Douglas states, first things first. The first challenge was that MSBuild can´t compile websites out-of-the-box. But Microsoft released a Web Deployment Project, that is like a MSBuild addin for deploying websites.

After installing it in both my local machine and the build server, I was good to go. But I lacked one more thing to make my MSBuild dreams come true. The MSBuild Community Tasks project. This project is a compilation of hundreds of incredibly useful MSBuild tasks. You´ll understand why tasks are so important later, but for now, just believe me: This Project ROX! So I downloaded it and again, installed in both my local machine and the build server.

I went on again with Douglas´s explanation and created my Team Build. Creating a Team Build couldn´t be easier using Visual Studio´s Wizard.

  1. Find the Folder that says Team Build Types on the Team Project you want to create the Team Build for.
  2. Right-Click and click new Team Build Type.
  3. From here on the wizard is pretty self-explanatory.

One catch here is that the build server must have Team Build Service installed and running. This server must also have a Windows Server edition running, so NO, you can´t use your local XP machine to use as a Team Build Server. I won´t get into many detail as to how to setup the build server since there are many articles out there that tell you how to do it. There is a great article by Vertigo Software that explains this task. You can read it here.

Well, having setup the build server correctly and with the Team Build created now I had to configure the Team Build to correspond to the requirements above.

The first thing I had to do was creating a Web Deployment Project. This can be easily done by right-clicking on the WebSite for which you want to create a deployment project and clicking on "Add Web Deployment Project...". A form shows up asking for the Name and Location of this new project (as shown above, the images belong to the Douglas Rohm article, credit goes to him).

After creating the Web Deployment project I went on to edit it manually. Yeah, that´s right, the part we love, code, XML files... lol...

So I open up the Site_deploy project by right-clicking on it and clicking Open Project File. The file was as below:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <ProductName>Multiplan.SIM</ProductName>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProductVersion>8.0.60403</ProductVersion>
        <SchemaVersion>2.0</SchemaVersion>
        <ProjectGuid>{E4AFA6CA-E268-48E8-9F43-D0DA54B0FD3D}</ProjectGuid>
        <SourceWebPhysicalPath>..\Site</SourceWebPhysicalPath>
        <SourceWebProject>{1447273E-BA67-429F-93BF-A2415DC125B2}|C:\TSProjects\bernardo\Multiplan\SIM\Main\VersaoAtual\Site</SourceWebProject>
        <SourceWebVirtualPath>/Site</SourceWebVirtualPath>
        <SccProjectName>SAK</SccProjectName>
        <SccLocalPath>SAK</SccLocalPath>
        <SccAuxPath>SAK</SccAuxPath>
        <SccProvider>SAK</SccProvider>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <DebugSymbols>true</DebugSymbols>
        <OutputPath>.\Debug</OutputPath>
        <EnableUpdateable>true</EnableUpdateable>
        <UseMerge>true</UseMerge>
        <SingleAssemblyName>Site_deploy</SingleAssemblyName>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
        <DebugSymbols>false</DebugSymbols>
        <OutputPath>.\Release</OutputPath>
        <EnableUpdateable>true</EnableUpdateable>
        <UseMerge>true</UseMerge>
        <SingleAssemblyName>
        </SingleAssemblyName>
    </PropertyGroup>
    <ItemGroup>
        <ProjectReference Include="..\..\..\..\..\Perlink\Providers\OracleMembershipProvider\Perlink.Providers.csproj">
            <Project>{A46C1155-C4D9-40DD-94A7-ABE7BE4092DF}</Project>
            <Name>Perlink.Providers</Name>
        </ProjectReference>
        <ProjectReference Include="..\Multiplan.Imobiliario.Objetos\Multiplan.Imobiliario.Objetos.csproj">
            <Project>{288B6FC0-086E-4E66-AC59-A3C4175A5A45}</Project>
            <Name>Multiplan.Imobiliario.Objetos</Name>
        </ProjectReference>
        <ProjectReference Include="..\Multiplan.Imobiliario.RegrasDeNegocio\Multiplan.Imobiliario.RegrasDeNegocio.csproj">
            <Project>{FFDD5DE5-3AC8-447E-830B-D8271FC918A6}</Project>
            <Name>Multiplan.Imobiliario.RegrasDeNegocio</Name>
        </ProjectReference>
        <ProjectReference Include="..\Multiplan.Sim\Multiplan.Sim.csproj">
            <Project>{961EC2E1-D635-411F-B11E-CF56FD130F6E}</Project>
            <Name>Multiplan.Sim</Name>
        </ProjectReference>
    </ItemGroup>
    <Import Project="$(MSBuildExtensionsPath)\Microsoft\WebDeployment\v8.0\Microsoft.WebDeployment.targets" />
</Project>

So I think: "Well that doesn´t mean a lot to me, so I better understand what it means!". And basically what it´s saying is how to build and deploy the website and what references this website has.

Now the only two things missing in this deployment file is the part that copies the files to the test site and the part that zips the built site into a zip file with the version number.

As a matter of fact both very easy to accomplish. Just remember to check that your web deployment project file includes the following Import directive:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\WebDeployment\v8.0\Microsoft.WebDeployment.targets" />

After that we just have to add a few couple lines to the end of the file (before the </Project> node):

This one must be added so we can reference the MSBuild Community Tasks project:

<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />

These two must be added so we can reference both the Version Task (responsible for incrementing the version numbers) and the Zip Task (responsible for zipping the output contents into a zip file):

<UsingTask AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" TaskName="MSBuild.Community.Tasks.Zip" />
<UsingTask AssemblyFile="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.dll" TaskName="MSBuild.Community.Tasks.Version" />

This directive below is responsible for telling the MSBuild engine that prior to building the solution the version number of the assembly must be incremented (so we can use it in our zip file later):

<Target Name="BeforeBuild">
    <Version RevisionType="Increment" VersionFile="BuildNumber.txt">
        <Output PropertyName="Major" TaskParameter="Major" />
        <Output PropertyName="Minor" TaskParameter="Minor" />
        <Output PropertyName="Build" TaskParameter="Build" />
        <Output PropertyName="Revision" TaskParameter="Revision" />
    </Version>
    <Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)" />
    <CreateItem Include="AssemblyFileVersion" AdditionalMetadata="Value=$(Major).$(Minor).$(Build).$(Revision)">
        <Output TaskParameter="Include" ItemName="AssemblyAttributes" />
    </CreateItem>
    <CreateItem Include="AssemblyVersion" AdditionalMetadata="Value=$(Major).$(Minor).$(Build).$(Revision)">
        <Output TaskParameter="Include" ItemName="AssemblyAttributes" />
    </CreateItem>
</Target>

The last one is the directive that tells the MSBuild engine to zip the built site and copy it to the test site:

<Target Name="AfterBuild">
    <Zip ZipFileName="E:\Sites\Multiplan\SIM\Archived\$(ProductName)_$(Major).$(Minor).$(Build).$(Revision).zip" Files="@(PrecompiledOutput)" />
    <Copy DestinationFiles="@(PrecompiledOutput->'e:\sites\multiplan\sim\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(PrecompiledOutput)" />
</Target>

Now that our team build is setup and our web deployment project is complete we are halfway to Continuous Integration.

Click here for part two of this article...

Technorati Tags: - - - - - - - -

Site Meter
Published Friday, September 01, 2006 7:17 PM by heynemann

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Team Build 101 (Part 2 of 2)

Friday, September 01, 2006 5:19 PM by while(availableTime>0) {
This is article part two. For part&amp;nbsp;one click here. We must now check to see if our team build is...

# Continuous Integration (CI) 整合資訊

Friday, September 15, 2006 8:36 AM by Refines.Info["Polo Lee"]
Agile 的 CI 概念在 Team System 架構中, Default 是沒有提供的,原因有很多 但結果是 目前功能上沒有這個選項, 只是 這不代表 Team System 不可能有 CI 流程,事實上...

# VSTS Links - 09/15/2006

Friday, September 15, 2006 10:30 AM by Team System News
D'Arcy Lussier on Storyboarding for Team System. Rob Caron talks about it as well.
Tan on Customizing...

Enter the text you see in the image:

Leave a Comment

(required) 
required 
(required)