Web developer from Sydney Australia. Currently using asp.net, mvc where possible.

Wednesday, October 20, 2010

Zipping Build Outputs using a Build File - MsBuld Series

We are continuing ths msbuild series, this post will focus on zipping the outputs of the build. To recap so far we have setup a batch file that can build and version our project. The output of this build is placed inside a folder called "build" at the top of projects directory structure.

We will zip up the outputs of the build so they can be easily distributed. To do this, the Zip build task that is part of the “MsBuld.Community.Tasks” library will be used. If you are not familiar with this library and how to setup then please read through my two previous posts to get up to speed.
We are going to create two zip files during our build:
  1. A zip of all binaries needed to run the application
  2. A zip of all source code needed to compile the application.
We are zipping up the source so we can provide an easy download of the source code for our application via codeplex, github etc. Similarly we can provide just a zip of the binaries for a specific version of our application.

1) Change the output directory to “build\bin”

Firstly we are going to change our build output directory inside visual studio so that the binaries are placed into a new folder called bin under the build directory “[project]\Build\Bin”. Having a sub directory removes the clutter from the root of our build directory so we can place our zip files there.

Below is the screen shot of the new location being set inside visual studio for our automated_build configuration.

Changing the output directory

2) Creating the Zip-Binaries target

We have already included the “MSBuild.Community.Tasks” targets in our build file, so only thing we need to do before using the zip task is to ensure that we have copied the ICSharpCode.SharpZipLib.dll binary into our “Tools\MsBuildCommunityTasks” directory. This binary is included in the MsBuildCommunityTasks download.

Now declare the Zip-Binaries target as follows
<Target Name="Zip-Binaries">
<ItemGroup>
<BinDirectoryFiles Include="$(BuildOutputDir)\bin\**" />
</ItemGroup>
<Zip Files="@(BinDirectoryFiles)" WorkingDirectory="$(BuildOutputDir)\bin\"
ZipFileName=".\$(BuildOutputDir)\Jobping.StickyBeak_Binaries_$(Major).$(Minor).$(Build).$(Revision).zip" />
</Target>
Notes on the Zip-Binaries target
  • BinDirectoryFiles – this variable references all files below the "build\bin” directory. These are the files that we will zip.
  • The WorkingDirectory attribute for the zip task specifies the root directory for the zip file. We speicify the “build\bin” directory as the root for our zip
  • We use the version information to name the resultant zip file.

2) Creating the Zip-Source target

Apart from the binaries we also want to distribute the source code. So, we are going to declare a Zip-Source target for our build file as follows:
<Target Name="Zip-Source">
<ItemGroup>
<SourceFilesExclude Include="**\.hg\**" />
<SourceFilesExclude Include="build**" />
<SourceFilesExclude Include="**\.*" />
<SourceFilesExclude Include="**\bin\**" />
<SourceFilesExclude Include="**\obj\**" />
<SourceFilesExclude Include="**\Test\**" />
<SourceFilesExclude Include="**\TestResults\**" />
<SourceFilesExclude Include="**\*.user" />
<SourceFilesExclude Include="**\*.suo" />
<SourceFilesExclude Include="**\*.cache" />
<SourceFilesExclude Include="**\*.vsmdi" />
<SourceFilesExclude Include="**\*.testsettings" />
</ItemGroup>
<ItemGroup>
<SourceFiles Include="**\*.*" Exclude="@(SourceFilesExclude)" />
</ItemGroup>
<Zip Files="@(SourceFiles)" 
ZipFileName=".\$(BuildOutputDir)\Jobping.StickyBeak_Source_$(Major).$(Minor).$(Build).$(Revision).zip" />
</Target>
Notes on the Zip-Source target
  • We generally want to zip up everything, so we include all files by using the wildcard “**\*.*” which means all files in all directories.
  • We specify a list of excludsions, these are source control files and other files that are generated or not necessary in order to build our application.
  • Getting the exclude list correct requires some testing, you should test your source zip by extracting it and making sure you can compile the solution.

3) Incorporating the Zip tasks into our default build

Since we can now created the two zip targets all we need to do is have our default build target depend on these targets, as follows:
<Target Name="Build" DependsOnTargets="Clean; VersionSolutionInfo; Compile; Zip-Source; Zip-Binaries">
<Message Text="Clean, VersionSolutionInfo, Compile, Zip-Source, Zip-Binaries"/>
</Target>
That’s it. Below is a screen shot of the kicking off a build and the resultant output in the build directory.

Build output

Screen shot of our ready to ship zips:

Build output directory

Resources:
This is the third post in the MsBuild series.

Shout it kick it on DotNetKicks.com

No comments: