Lately I have found myself implementing multiple builds with TFS that basically just call PowerShell scripts. One of the issues that I have with these scripts is getting good error reporting back to TFS.
Specifically, the issue comes down to the fact that non-cmdlet commandline tools generally return error codes and are incapable of throwing PowerShell errors when they fail. To get the commandline tools working like cmdlets, I took a page out of James Kovacs book (blog?) and implemented a Exec function:
function Exec([scriptblock]$cmd) { $result = & $cmd if ($LastExitCode -ne 0) { throw $result } else { foreach ($line in $result) { Write-Host $line } } }
Which you can simply call with:
Exec { sometool.exe "with parameters" }
In the case of an error, it will throw an exception. Otherwise, the output will be written to standard output.
In the context of TFS, I put together a nice sequence that will fail the build if an exception is thrown.
First, I include the Exec
function. You can find it on github gist. This one is slightly modified to output the last 50 lines of output when an error occurs.
Next, wrap all of your Exec
calls in a try/catch
like so:
try { Exec { sometool.exe "with parameters" } } catch { Write-Error $_ Exit 1 }
Now presumably, you will be calling your PowerShell script with an InvokeProcess
activity from your Build Process Template. In the scope that the activity will be run, create a variable called ExitCode
of type Int32
:
Now set the Result
field of the InvokeProcess
activity to the new variable:
This will set the return code of your PowerShell build script into the variable you created.
Now add a SetBuildProperties
activity after the InvokeProcess
activity. In the properties of the SetBuildProperties
activity, in the PropertiesToSet
field check off Status
. Then set the Status
field to
If(ExitCode = 0, BuildStatus.Succeeded, BuildStatus.Failed)
Now when your script throws an error, it will return an exit code of 1 and that will be caught by TFS which will fail the build. I acknowledge that it is ironic to convert the tool’s return code to an exception and then back to a return code, but that is what is necessary to have it flow through to TFS correctly.
No comments:
Post a Comment