Introduction
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
<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" />
<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 that 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 " 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.
<ItemGroup>
<NuGetPackageConfigs Include="$(MSBuildStartupDirectory)\**\packages.config" />
</ItemGroup>
<Target Name="LoadNuGetPackages">
<Message Importance="high" Text="
Retrieving packages for %(NuGetPackageConfigs.Identity)" />
<Exec Command=""$(SrcPath)\.nuget\nuget"
install "%(NuGetPackageConfigs.Identity)"
-o "$(SrcPath)\packages"" />
</Target>
Final ci.msbuild
By adding both targets to our msbuild script, we end up with the 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.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Compile">
<PropertyGroup>
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
<DefineSolutionProperties>false</DefineSolutionProperties>
<RootPath>$(MSBuildProjectDirectory)</RootPath>
<SrcPath>$(RootPath)\src</SrcPath>
<ReportsPath>$(RootPath)\reports</ReportsPath>
<ToolsPath>$(RootPath)\tools</ToolsPath>
<Packages>$(SrcPath)\packages</Packages>
</PropertyGroup>
<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" />
<MSBuild Projects="@(ProjectFiles)"
ContinueOnError="false"
Targets="Clean"
Properties="Configuration=$(Configuration)" />
</Target>
<ItemGroup>
<NuGetPackageConfigs Include="$(MSBuildStartupDirectory)\**\packages.config" />
</ItemGroup>
<Target Name="LoadNuGetPackages">
<Message Importance="high"
Text="Retrieving packages for %(NuGetPackageConfigs.Identity)" />
<Exec Command=""$(SrcPath)\.nuget\nuget"
install "%(NuGetPackageConfigs.Identity)"
-o "$(SrcPath)\packages"" />
</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.
CodeProject
The post CI with Jenkins, MSBuild, Nuget and Git part 2 appeared first on Marco Franssen.