Skip to content
tcabanski edited this page Dec 19, 2011 · 7 revisions

MsBuildTools is a set of MSBuild targets and other helpful tools that make it easier to seup a continuous integration build process. It includes support for building on the command line and under TeamCity. It also supports using public and private Nuget without putting the packages in source control.

##Usage The repository is designed to be used as a Git Submodule.

  • Make this a submodule of your repository. Use tools\msbuild as the path.
  • Copy the files in FilesToPlaceInProjectRoot to the root of your project.
  • Edit the build.proj file copied in the previous step based on your project using the instructions shown below.

If you are unfamiliar with how Git submodules work, see Git Book - Submodules for more information.

##Setting up your solution

The build process relies on the Nuget's support for projects that do not have the packages folder checked into source control. This makes the repository smaller and faster. You must enable this feature for your solution using the instructions in the Nuget Documentation. If you are using a secure private Nuget server that requires logon credentials, copy the files in the PatchedNugetExeAllowsCredentials folder over the files Nuget places in .nuget under your project and place the credentials for each private Nuget server into the nuget.exe.config file.

##Configuring your Project

The build script assumes your directory structure has the solution file, the build file (build.proj) and the supporting files found in FilesToPlaceInProjectRoot in the root directory. Your application projects should go in one directory and your tests should go in another. By convention, the build tools assume you have your tests in [project root]\tests. If you are going to use a different directory, you will need to set the MSBuild property $(TestProjectDir) to the absolute path of your test directory. For example, "$(MSBuildProjectDirectory)\testProjects".

You also need to setup a common file to contain version information for all your projects if you want to take advantage of the version stamping feature:

  1. Place an empty file named CommonAssemblyInfo.cs next to your solution file
  2. Reference it as a link in all your projects
  3. Remove the ComVisible, AssemblyFileVersion, AssemblyCopyright, AssemblyConfiguration, AssemblyCompany and AssemblyProduct assembly attributes from Properties\AssemblyInfo.cs in all projects

##Configuring your Build.Proj File

You must setup your build.proj to contain specific information about your project. You may also extend various features of the build to perform custom operations.

###Setup Your Directory Structure

###Specifying a Binary Distribution

The binary distribution feature will produce a zip containing your binary files in a single folder. The zip file is placed in BuildOutput\distribution and is named $(ProductName)_[full version]_[configuration].zip.

You specify the files to copy into the binary distribution using the the BinInclude property like this:

<!-- Binary files to publish -->
<PropertyGroup>
    <BinInclude>
        path\*.*; <!-- include all files in path -->
        path\**\*.*; <!-- all files in path and all subdirectories of path -->
    </BinInclude>
</PropertyGroup>

You may also optionally use BinExclude to filter out certain files included by BinInclude. For example:

<!-- Binary files to publish -->
<PropertyGroup>
    <BinExclude>
        path\*.user; <!-- exclude all files in path named [something].user -->
        path\**\*.user; <!-- exclude all files in path and all subdirectories of path named [something].user -->
    </BinInclude>
</PropertyGroup>

###Customizing

The standard build script offers a series of extension points you can use to change or extend the behavior of the build.

####Adding Additional Information to the Name of Zip Distributions

The value in AdditionalZipQualifier will be added to all distribution zip files. For example, the following xml will add the text "_static_[value of OtherProperty]" to the name of the zip file. Note that this additional text is placed right before the ".zip" extension:

<PropertyGroup>
    <AdditionalZipQualifier>_static_$(OtherProperty)</AdditionalZipQualifier>
</PropertyGroup>

####Excluding Certain Tests Under Certain Conditions

Sometimes you may need to skip tests under certain conditions. For example, MyProject tests should not be run when building for a production database configuration since the tests might end up modifying the production database. To do this, you have to specify which test are environment specific and under what conditions they should be skipped.

Do not confuse the concept of environment with a build configuration. MSBuildTools allows you to setup an environment property that has nothing at all to do with the MSBuild/Visual Studio.NET configuration. This way you are not forced to create a project configuration for each and every environment. You are welcome to use the project configuration to drive environment options, but you are not forced to do so.

For this to work, the TeamCity configuration must not have a step to run unit tests independent of the build script. If you have defined a TeamCity step to run unit tests, reconfigure the build step to perform any code coverage integration and remove the TeamCity unit test step.

First, specify the environment specific tests in the NUnitTestItem item group. For example, in The following project both test projects are environment specific:

<!-- NUnit Tests -->
<ItemGroup>
    <NUnitTestItem Include="MyProject.Tests.Unit">
        <EnvironmentSpecific>true</EnvironmentSpecific>
    </NUnitTestItem>
    <NUnitTestItem Include="MyProject.Tests.Integration">
        <EnvironmentSpecific>true</EnvironmentSpecific>
    </NUnitTestItem>
</ItemGroup>

You then set the SkipEnvironmentSpecificTests property to "true" when the necessary condition for skipping tests is met. For example, MyProject should only run tests for the UAT environment configuration when building under Team City and on the debug environment configuration when building outside Team City:

<PropertyGroup>
    <SkipEnvironmentSpecificTests Condition="($(DatabaseTargetConfiguration) != 'Debug' and !$(InTeamCity)) or    ($(DatabaseTargetConfiguration) != 'UAT' and $(InTeamCity))">true</SkipEnvironmentSpecificTests>
</PropertyGroup>

Clone this wiki locally