$ cat "

Failing a TeamCity Build from a PowerShell Build Step

"

One of the most versatile and useful build steps in TeamCity for a Windows based shop is the PowerShell build step. Unfortunately, there is a quirk in the behaviour of the PowerShell build step that occurs if you use a PowerShell script file, rather than an inline script in the build step definition. The problem is that PowerShell does not return the actual exit code from the script when invoked with the -File parameter (see https://connect.microsoft.com/PowerShell/feedback/details/777375/powershell-exe-does-not-set-an-exit-code-when-file-is-used) which in turn results in TeamCity not being able to detect if the script failed. So, a failing script does not break the build. This is a major issue.

Fortunately TeamCity provides a couple of different ways to solve this problem.

Fail on Error Output

One easy, but a bit clumsy, way is to add a Build Failure Condition that fails the build when an error message is logged by the build runner (https://confluence.jetbrains.com/display/TCD9/Build+Failure+Conditions#BuildFailureConditions-Commonbuildfailureconditions), no matter why or what step produced the error. This will solve the problem, as long as the script actually writes to stderr (error output) when the error occurs. It might also mean that the build is failed for errors that actually did not matter that much.

One way to control the weight given to errors from a PowerShell script is to configure the Error Output parameter in the build step to either warning or error. For the script to fail the build the Error Output parameter must be set to error (https://confluence.jetbrains.com/display/TCD9/PowerShell). So, for scripts that are non-vital to the build where an error could be acceptable, set the Error Output as warning, which means that the output will appear as a warning in the actual build log. Setting it to error combined with the failure condition mentioned above will cause the build to fail when the script writes anything to stderr.

Service Messages

To get more fine grained control over when a script should fail the build TeamCity provides another approach: Service Messages (https://confluence.jetbrains.com/display/TCD9/Build+Script+Interaction+with+TeamCity#BuildScriptInteractionwithTeamCity-ReportingBuildProblems).

Through Service Messages the script can write output following a predefined format to stdout (NOT stderr). To fail the build with using this approach you can ouput text following this format:

##teamcity[buildProblem description='<description>' identity='<identity>']

Description is required, but Identity is optional information.

Here is an example of how that could look in an actual PowerShell script:

Try
{
    # Do stuff that might fail
}
Catch
{
    # Get the current error
    $ErrorMessage = $_

    # Write a message to stdout to let TeamCity know that the script failed.
    # The exit code is not returned properly to TeamCity due to issues with invoking
    # PowerShell script files using -File
    # Observe that this message is written with Write-Host rather than Write-Error,
    # to make sure the message is written to stdout rather than stderr
    Write-Host "##teamcity[buildProblem description='$ErrorMessage']"

    Write-Error -Message $ErrorMessage

    exit 1
}

exit 0
Written by Erik Öjebo 2015-08-12 09:14

    Comments