3

I have put together a PSake (v2.0) build script, and the script is setting the $psake.build_success property as true even thought the call to MSBuild fails. Can anyone advise me on how to alter the script so that the $psake.build_success property will correctly return false when the MSBuild call fails?

My PSake build script is as follows:

properties {
    $solutionFile = 'SOLUTION_FILE'
    $buildSuccessfulMessage = 'Solution Successfully Built!'
    $buildFailureMessage = 'Solution Failed to Build!'
    $cleanMessage = 'Executed Clean!'
}

task default -depends BuildSolution 

task BuildSolution
{
    msbuild $solutionFile /t:Clean,Build
    if ($psake.build_success) 
    {
        $buildSuccessfulMessage
    } 
    else 
    {
        $buildFailureMessage
    }
}
Tangiest
  • 43,737
  • 24
  • 82
  • 113
  • 3
    Currently psake has a bug whereby hanging `{` will only echo the contents and not EXECUTE them. So, change to `task BuildSolution {` and you should have better results. – Brett Veenstra Jul 22 '10 at 16:52
  • Brett, Thanks for the info, much appreciated. If you were to leave it as an answer below, I would accept it as the official answer. – Tangiest Jul 22 '10 at 20:48

4 Answers4

3

Is PowerShell's native $lastExitCode (i.e., WIn32 ExitCode) any use in the context? I'd be guessing that the built in one is only relevant when you're invoking a psake-related cmdlet.

i.e., replace the check with

if($lastexitcode -eq 0) {

Disclaimer: Only podcast level experience with psake :D

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
  • 1
    Thanks Ruben, because the actual call to MSBuild is actually successful, but the build operation it initiates fails, this wouldn't work. +1 for a useful code snippet I 'll be using in the future. – Tangiest Dec 01 '09 at 16:29
  • 1
    I'm pretty sure msbuild should set `lastExitCode` - how many levels deep are you trying to go? Normally any msbuild execution failures should just bubble up (i.e. any child builds that fail return a non-zero exit code and that triggers the parrent failings and so on. This discusses the concept:- http://code.google.com/p/psake/issues/detail?id=9 – Ruben Bartelink Dec 02 '09 at 08:33
3

The issue seems to be that the call to MSBuild operation actually completes successfully, whilst the build operation it initiates fails. The way I was able to get around this was to pipe the output of the MSBuild call to a text file, and then parse the file for the string "Build Failed". If it contained the string, obviously the build failed.

My PSake build script is as follows:

properties {
    $solutionFile = 'SOLUTION_FILE'
    $buildSuccessfulMessage = 'Solution Successfully Built!'
    $buildFailureMessage = 'Solution Failed to Build!'
    $cleanMessage = 'Executed Clean!'
}

task default -depends Build 

task Build -depends Clean {
    msbuild $solutionFile /t:Build /p:Configuration=Release >"MSBuildOutput.txt"
}

task Clean {
    msbuild $solutionFile /t:Clean 
}

and in my calling script:

function Check-BuildSuccess()
{
    return (! (Find-StringInTextFile  -filePath .\MSBuildOutput.txt -searchTerm "Build Failed"))
}

function Is-StringInTextFile
(
    [string]$filePath = $(Throw "File Path Required!"),
    [string]$searchTerm = $(Throw "Search Term Required!")
)
{
    $fileContent = Get-Content $filePath    
    return ($fileContent -match $searchTerm)
}
Tangiest
  • 43,737
  • 24
  • 82
  • 113
1

There is the psake Exec command that you can wrap msbuild with and a powershell error is thrown.

Exec {
     msbuild $solutionFile "/p:Configuration=$buildConfiguration;Platform=$buildPlatform;OutDir=$tempOutputDirectory"
}
Thorb
  • 81
  • 6
0

Neither $LastExitCode or $_ worked for me. This did however:

$buildArgs = "MySolution.sln", "/t:Build", "/p:Configuration=Debug"
$procExitCode = 0
$process = Start-Process -FilePath "msbuild" -ArgumentList $buildArgs -NoNewWindow -PassThru
Wait-Process -InputObject $process
$procExitCode = $process.ExitCode

#aha! msbuild sets the process exit code but powershell doesn't notice
if ($procExitCode -ne 0)
{
    throw "msbuild failed with exit code $procExitCode."
}

P.S. If you use this in production I recommend adding -timeout handling to Wait-Process

Chris
  • 448
  • 5
  • 9