Blog.

CI with Jenkins, MSBuild, Nuget and Git part 2

Marco Franssen

Marco Franssen /

4 min read636 words

Cover Image for CI with Jenkins, MSBuild, Nuget and Git part 2

In part 1 of this blog series we had a look at a very basic MSBuild script which enables us to compile our projects. For doing this I provided you guys with a simple batch file to make it even more simple to execute the build script.

In this episode we will focus on cleaning the folders before building again and getting the Nuget packages using Nuget package restore. The latter I will explain further for you first.

Nuget package restore can be enabled in Visual studio. A best practice is to enable this always, because then we won't have to put all Nuget packages in source control. By enabling it, every team member will download the missing packages automatically when building his project in Visual Studio. However the build server won't do this by default so we create a custom target in our build script to make this happen.

Clean target

ci.msbuild
<!-- The Clean Target -->
<ItemGroup>
    <ProjectFiles Include="**\*.csproj" />
</ItemGroup>
<Target Name="Clean">
    <Message Importance="high" Text="Cleaning folders" />
    <RemoveDir Directories="$(ReportsPath)" Condition="Exists('$(ReportsPath)')" />
    <MakeDir Directories = "$(ReportsPath);$(ReportsPath)\MSpec;$(ReportsPath)\Coverage" />
    <!-- Clean the source code projects -->
    <MSBuild Projects="@(ProjectFiles)"
             ContinueOnError="false"
             Targets="Clean"
             Properties="Configuration=$(Configuration)" />
</Target>

This target will clean all our directories based on the project output folders for the given configuration. So if you provide debug it will clean the /bin/Debug folder. We use a ItemGroup to search for all the project files so we can use them in a msbuild task for cleaning the project outputs.

Please note we also recreate the reports directory where we will store our unit test reports etc. We will create a target for this in the following part of this blog series.

As you can see quotes are being encoded as &quot; in out tasks.

LoadNuGetPackages target

Also for the LoadNugetPackages we use a ItemGroup to search for files called packages.config. Those files are used as a parameter for Exec task which will execute nuget.exe.

<!-- The LoadNuGetPackages Target -->
<ItemGroup>
    <NuGetPackageConfigs Include="$(MSBuildStartupDirectory)\**\packages.config" />
</ItemGroup>
<Target Name="LoadNuGetPackages">
    <Message Importance="high" Text="Retrieving packages for %(NuGetPackageConfigs.Identity)" />
    <Exec Command="&quot;$(SrcPath)\.nuget\nuget&quot; install &quot;%(NuGetPackageConfigs.Identity)&quot; -o &quot;$(SrcPath)\packages&quot;" />
</Target>

Final ci.msbuild

By adding both targets to our msbuild script we end up with following build script. Please note the DependsOnTargets attribute added on our Compile target. This will make sure Clean and LoadNuGetPackages are executed first. When using Nuget package restore your solution will contain a folder called .nuget. In this folder the Nuget executable is located. Also make sure this executable is committed to your source control so the build server later on will have access to it.

ci.msbuild.xml
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
         DefaultTargets="Compile">
  <PropertyGroup>
    <Configuration>Debug</Configuration>
    <Platform>AnyCPU</Platform>
    <DefineSolutionProperties>false</DefineSolutionProperties>

    <!-- General Paths -->
    <RootPath>$(MSBuildProjectDirectory)</RootPath>
    <SrcPath>$(RootPath)\src</SrcPath>
    <ReportsPath>$(RootPath)\reports</ReportsPath>
    <ToolsPath>$(RootPath)\tools</ToolsPath>
    <Packages>$(SrcPath)\packages</Packages>
  </PropertyGroup>

  <!-- The Clean Target -->
  <ItemGroup>
    <ProjectFiles Include="**\*.csproj" />
  </ItemGroup>
  <Target Name="Clean">
    <Message Importance="high" Text="Cleaning folders"/>
    <RemoveDir Directories="$(ReportsPath)" Condition="Exists('$(ReportsPath)')" />
    <MakeDir Directories = "$(ReportsPath);$(ReportsPath)\MSpec;$(ReportsPath)\Coverage" />
    <!-- Clean the source code projects -->
    <MSBuild Projects="@(ProjectFiles)"
             ContinueOnError="false"
             Targets="Clean"
             Properties="Configuration=$(Configuration)" />
  </Target>

  <!-- The LoadNuGetPackages Target -->
  <ItemGroup>
    <NuGetPackageConfigs Include="$(MSBuildStartupDirectory)\**\packages.config" />
  </ItemGroup>
  <Target Name="LoadNuGetPackages">
    <Message Importance="high" Text="Retrieving packages for %(NuGetPackageConfigs.Identity)" />
    <Exec Command="&quot;$(SrcPath)\.nuget\nuget&quot; install &quot;%(NuGetPackageConfigs.Identity)&quot; -o &quot;$(SrcPath)\packages&quot;" />
  </Target>

  <!-- The Compile Target -->
  <Target Name="Compile" DependsOnTargets="Clean;LoadNuGetPackages">
    <Message Importance="high" Text="Compiling core projects"/>
    <MSBuild Projects="$(SrcPath)\MyProject.Core\MyProject.Core.csproj"
             Properties="Configuration=$(Configuration);Platform=$(Platform)" />
    <MSBuild Projects="$(SrcPath)\MyProject.Web\MyProject.Web.csproj;$(SrcPath)\MyProject.Win\MyProject.Win.csproj"
             Properties="Configuration=$(Configuration);Platform=$(Platform)"
             BuildInParallel="true" />
  </Target>
</Project>

Finally we are getting somewhere. When we execute our batch file now it will first clean our directories, then get all Nuget packages if they are missing and then it will compile our assemblies.

In the next part we will add a target for running our Mspec tests and generating a code coverage report based on those test assemblies. So hang on and share this article with your friends.

You have disabled cookies. To leave me a comment please allow cookies at functionality level.

More Stories

Cover Image for CI with Jenkins, MSBuild, Nuget and Git part 4

CI with Jenkins, MSBuild, Nuget and Git part 4

Marco Franssen

Marco Franssen /

In part 1, 2 and 3 I showed you how to create a simple MSBuild script and how to execute it from the command line. We had a look at how to clean your output directories, download the Nuget packages, compile your code, run MSpec tests and creating a code coverage report. In this last part of this series I will show you how to integrate it with Jenkins. First of all we want Jenkins to pull the latest code from Github as soon as somebody has pushed new code to Github. To do this we need to install…

Cover Image for CI with Jenkins, MSBuild, Nuget and Git part 3

CI with Jenkins, MSBuild, Nuget and Git part 3

Marco Franssen

Marco Franssen /

In the previous parts (part 1, part 2) of this series I described how to clean, download Nuget packages and build your solution using MSBuild. In this part I will explain you how to create a MSpec MSBuild target and a Code coverage MSBuild target. MSpec is a testing framework which enables you to write living specifications. Using the MSpec console runner you can easily generate an html report. This report can later on be published using the Jenkins report plugin. By publishing this report we h…

Cover Image for CI with Jenkins, MSBuild, Nuget and Git part 1

CI with Jenkins, MSBuild, Nuget and Git part 1

Marco Franssen

Marco Franssen /

Very lately I have worked on setting up some continuous integration (CI) using MSbuild for my c# project. In this blog series I will explain to you how to set up continuous integration. First of all we will start with creating a MSBuild script which will compile our code. We will also create a small batch file for easy executing the MSbuild script. When that is in place, we will add several targets to the build script to run for example unit tests, integration tests, code coverage, packaging e…

Cover Image for Recap my online year 2012

Recap my online year 2012

Marco Franssen

Marco Franssen /

The year 2012 was for me a year that went way to fast. In the year 2012 I learned a lot new stuff, wrote several blog posts and read lots of blog posts and articles. First of all I want you to give a list of all blog posts I wrote this year. You can find the complete list here http://marcofranssen.nl/2012/ and here http://marcofranssen.nl/2012/page/2/. JavaScript http://marcofranssen.nl/writing-modular-javascript-without-polluting-the-global-namespace/ http://marcofranssen.nl/knockout-js-mapp…