Given a solution or project file that you've already created it is a simple matter to call MSBuild against that particular file, but what I really wanted to do is have a separate build file that would do the lot.
So how did I go about picking it up?
I started with a REALLY simple app (can't stress enough how simple it was) and added an XML file to the solution that would act as my build file. On a side note, I later changed the file extension to .proj and the file maintained intelisense.
I then copy/pasted the following lines into the file:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
The following is an overview of my observations of how I got my app to build and execute tests.
The first thing I played with was indicating which solution to build. This is what I ended up with:
<PropertyGroup>
<SolutionDir>..</SolutionDir>
<SpecificSolutionToBuild></SpecificSolutionToBuild>
</PropertyGroup>
<Choose>
<When Condition="'$(SpecificSolutionToBuild)' == ''">
<ItemGroup>
<SolutionsToBuild Include="$(SolutionDir)\TeamCityTestApp1.sln" />
<SolutionsToBuild Include="$(SolutionDir)\TeamCityTestApp1Alternate.sln" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<SolutionsToBuild Include="$(SolutionDir)\$(SpecificSolutionToBuild)" />
</ItemGroup>
</Otherwise>
</Choose>
<Target Name="Compile">
<MSBuild Projects="@(SolutionsToBuild)" Properties="OutputPath=$(OutputDir);Configuration=Release;DebugType=none;" />
</Target>
The above code introduces the Choose element and the Properties attribute in the MSBuild element.
Next I wanted to set the build output directory. Here's what I came up with:
Next I wanted to set the build output directory. Here's what I came up with:
<ItemGroup>It was while I was figuring this out that it dawned on me that if I need to refer to multiple items then I always need to create an ItemGroup.
<FilesInOutputDir Include="$(outputDir)\*"></FilesInOutputDir>
</ItemGroup>
<Target Name="CleanOutputPath">
<Delete Files="@(FilesInOutputDir)" />
</Target>
<Target Name="Compile" DependsOnTargets="CleanOutputPath">
<MSBuild Projects="@(SolutionsToBuild)" Properties="OutputPath=$(outputDir);Configuration=Release;DebugType=none;" />
</Target>
The next thing that was essential to figured out was getting unit tests executed. This was my first introduction to the use of custom build tasks.
For this I downloaded MSBuild.Community.Tasks.msi from msbuildtasks.tigris.org.
To get this working all you need to do is import the MSBuild.Community.Tasks.Targets at the top of your build file like so:
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />and to call:
<Target Name="RunUnitTests" DependsOnTargets="Compile">
<ItemGroup>
<AssembliesToTest Include="$(OutputDir)\TeamCityTestApp1.Tests.dll" />
</ItemGroup>
<NUnit ToolPath="$(NUnitToolsDir)"
DisableShadowCopy="true"
Assemblies="@(AssembliesToTest)"
OutputXmlFile="$(BuildDir)\UnitTestResults.xml"/>
</Target>
In this example I've created an item group to encompass which assemblies to test. In this situation this isn't really required as I'm only testing one dll, however if I were testing multiple dll's then this would be the approach to use.
I know a lot of this information was fairly basic, but thought it might be useful for those who haven't worked with msbuild before.
Enjoy!