Derik Whittaker

Syndication

News


From 0 to doing solution builds w/ PSake–Part 1 of N

Recently I decided I would kill two birds with one stone, I figured I would learn a bit of Powershell and setup some build scripts for our project.  I have been wanting to play around with Powershell for the longest time but could never really either find the time or the reason to play with it.  So I figured that setting up build scripts would be a perfect use of my time (I know I could have choose any other build language/framework but PSake meet my need).

In this post I will walk you though how to setup a build from scratch.  I will warn that because I am a COMPLETE NOOB with powershell it is very likely that my powershell code is less than optimal but it meets my needs.

In my script we are going to accomplish 3 things:

  1. Setup a PSake Task to perform a clean on our solution
  2. Setup a PSake Task to perform a build on our solution
  3. Setup a PSake Task to run Tests in our solution

Before you continue I would suggest you download PSake and read the Readme.markdown script because this will tell you how to setup PSake to be run via Poweshell.  Once you have read the markdown file you can continue.

Creating your shell ps1 file.

You will want to create a build file to put the following code into.  Call it build.ps1 for our purposes.

Adding the Clean Task

The raw PSake ‘Task’ for the clean. 

task Clean {
  Invoke-Clean "My Solution" "..\Subfolder\MySolution.sln"  
}

As you can see from the task above this is just a pass through call into another method called Invoke-Clean.  I have done this because over time I expect to build out multiple build scripts, one per application, and I don’t want to duplicate the code which does a clean in each script.

Here is the actual Invoke-Clean function

function Invoke-Clean
{  [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)] [string]$BuildName = $null,
        [Parameter(Position=1,Mandatory=1)] [string]$SolutionFileWithPath = $null
        )
    
    Write-Host "Running Clean for" $BuildName "on Solution @" $SolutionFileWithPath
    
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe /verbosity:m /t:Clean $SolutionFileWithPath
}

The code above is doing 2 things. 

  1. I an writing to the host (aka console) that I am running a clean for the given build
  2. I am directly referencing the msbuild.exe from the folder.  Now with PSake you don’t always have to do this because it just ‘knows’ where msbuild is located.  However, I am building a silverlight app and the version of msbuild that PSake was finding was wrong and this was my solution for this.

Adding the Compile Tasks

When doing a compile we are going to simply call out to MSBuild and allow it to do its thing.  Below is the PSake task for doing a compile

task Compile -depends Clean {
  
  Invoke-Build "My solution" "..\Subfolder\MySolution.sln"  
    
}

Again the task above is just wrapper call around the Invoke-Build function.  It is the Invoke-Build function which is doing all the heavy lifting.  Below is our function.

It is important to point out that our Compile task depends on the Clean task.  This means that the Clean task will be run prior to the actual compile.

function Invoke-Build
{  
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)] [string]$BuildName = $null,
        [Parameter(Position=1,Mandatory=1)] [string]$SolutionFileWithPath = $null
        )
    
    Write-Host "Running Build for" $BuildName "on Solution @" $SolutionFileWithPath
    
    C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe /verbosity:m $SolutionFileWithPath
}

The Invoke-Build above is also calling to a specific version of the MSBuild but this time rather than doing a clean it is doing a compile.  Of course if you want to perform more actions via MSBuild you can find the full list of command line switches on MSDN.

Adding the Test Tasks

The last task I want to build is the testing task.  Because our team is using MSTest the code below is for this.  if you are using NUnit or any other testing framework the code should be close to this but of course calling the correct runner exe.

task Test -depends Compile, Clean {
  
  Invoke-MSTest "MyTestDll.dll" "..\Subfolder\UnitTests\bin\Debug\MyUnitTests.dll" "MyUnitTests.dll.trx"     
  
}

Our Test task above is pretty simple.  We are passing in 3 values, Display name, the dll to test and because this is MSTest I am providing the name of the output file I want generated with the test results.

Below is the implementation for Invoke-MSTest.

function Invoke-MSTest
{
  [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)] [string]$TestName = $null,
        [Parameter(Position=1,Mandatory=1)] [string]$TestDll = $null,
        [Parameter(Position=2,Mandatory=1)] [string]$ResultTrx = $null
        )
        
    Write-Host "Running Tests for" $TestName "Located @" $TestDll " Output to:" $ResultTrx
    
    
    if ( Test-Path $ResultTrx )       
    {
        Write-Host "Found" $ResultTrx "it will be deleted prior to running the test"
        Remove-Item $ResultTrx
    }       
    
    $result = mstest /testcontainer:$TestDll /resultsfile:$ResultTrx
       
    foreach( $line in $result )
    {
        if ( $line -ne $null )
        {
            if ( $line.StartsWith("Passed") -ne $true )
            {
                $line
            }
        }
    }
}

Looking at the Invoke-MSTest function above you can see I am doing more than simply making a call out to MSTest. I am doing 2 specific things.

  1. I am checking to see if there is an existing output file and if there is I am deleting it
  2. I am only outputting the failure test results to the console.  This allows me to remove all the extra noise of passed tests.

As you can see from above getting up and running w/ PSake is not that hard and does not take much effort.

Till next time,


Posted 02-04-2012 10:16 AM by Derik Whittaker
Filed under: ,

[Advertisement]

Comments

Artur Dorochowicz wrote re: From 0 to doing solution builds w/ PSake–Part 1 of N
on 02-04-2012 12:09 PM

You don't need to specify full path to msbuild. Psake adds proper directories to PATH environment variable based on Framework option of Invoke-psake. You can also set Framework in the build script itself.

In your case seems like the following will do:

${framework} = '4.0'

Derik Whittaker wrote re: From 0 to doing solution builds w/ PSake–Part 1 of N
on 02-04-2012 12:47 PM

@Arthur,

Yes you are correct, HOWEVER.  As i said i am building a Silverlight project and when i did not do the full path to MSBuild i got an error telling me that the Silverlight SDK was not installed.

Putting the full path is a solution to this problem.

I have already spoken with James and he mentioned he may have a patch for this so others will not have to put the full path

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)