Friday, September 2, 2011

Creating a Local Build With psake, Part 1: Compiling

Often there is more to building a solution than just compiling with Visual Studio. If you’re strict about your Continuous Integration process you’d probably want to make sure that the solution compiles, migration of the database doesn’t fail (if you have one), all the tests are green etc before you check in. For this reason I like to create a local build, something very similar to the build running on a CI server. My preferred choice for build automation is psake, a tool written in PowerShell. “It avoids the angle-bracket tax associated with executable XML by leveraging the PowerShell syntax in your build scripts.” Since PowerShell is a programming language in itself you can pretty much do everything you would possibly like, including integration with the .NET Framework.

Now, let’s compile our solution with psake.

Assuming that I have the following folder structure.


Download psake from and put the content (just the files) in \tools\psake\ . There is a bug in the current version of psake where it’s not possible to set framework version through $framework global variable in the build script. You therefore have to edit \tools\psake\psake.ps1 and set line 13 to:

[string]$framework = '4.0'

if you have a .NET 4.0 solution.

Create a file called build.ps1 in the build folder and include this in the file:

$framework = '4.0'

properties {
    $base_dir = resolve-path .\..
    $source_dir = "$base_dir\src"
    $config = "Debug"

task default -depends local
task local -depends compile

task compile {
    exec { msbuild  $source_dir\ContinuousDelivery.sln /t:Clean /t:Build /p:Configuration=$config /v:q /nologo }

With psake you can set up tasks with dependencies between them. If you run this with psake without specifying a task it will run the “default” task. As you can see I have created a task “local” in which “default” is dependent on. “local” is then dependent on the task “compile” where we call out to msbuild to actually do the compilation. The call is wrapped in an exec-function defined by psake. If the command line program we call out to fails, psake will automatically throw an exception and fail the build.

To make it easier to run the build script I like to wrap the invocation in a simple bat-file called build.bat at the root of the project:

@echo off
powershell.exe -NoProfile -ExecutionPolicy unrestricted -Command "& { .\tools\psake\psake .\build\build.ps1 %*; if ($lastexitcode -ne 0) {write-host "ERROR: $lastexitcode" -fore RED; exit $lastexitcode} }" 

Now, open a command line and navigate to your project directory and run build.bat:


Congratulations! You’ve compiled your solution with psake.

You can download the source code from GitHub.

No comments:

Post a Comment