Eduardo Hernández
Eduardo Hernández

Reputation: 403

How do you make a custom Visual Studio Team Services build task fail (using PowerShell)?

I created a Visual Studio Team Services extension that provides several build tasks. All tasks are implemented as PowerShell scripts.

Everything seemed to work as expected but then I realised that when a task had an error that did not break the build, as it should.

I assumed that a PowerShell script returning a non-zero exit code would break the build, but it doesn't. To confirm it, I created a very simple task with this line only:

exit 1

and checked that the build succeeds.

I have also found out that uncaught exceptions in the script do cause the build to fail.

Therefore, how should failures be notified from build tasks?

UPDATE: There are the task.json and script I am using:

task.json:

{
 "id": "7CA6E75B-0700-4723-83A7-C167EA514988",
 "name": "ExampleTask",
 "friendlyName": "Example build task",
 "description": "Example build task for development purposes",
 "author": "eduardomhg",
 "category": "Utility",
 "visibility": [
   "Build",
   "Release"
 ],
 "demands": [],
 "version": {
   "Major": "0",
   "Minor": "0",
   "Patch": "1"
 },
 "minimumAgentVersion": "1.83.0",
 "instanceNameFormat": "Example Task",
 "groups": [
       {
           "name":"advanced",
           "displayName":"Advanced",
           "isExpanded":false
       }
   ],
 "execution": {
   "PowerShell": {
     "target": "$(currentDirectory)\\ExampleTask.ps1",
     "argumentFormat": "",
     "workingDirectory": "$(currentDirectory)"
   }
 }
}

ExampleTask.ps1:

 Write-Host "Executing example task..."
 exit 1

Upvotes: 1

Views: 1617

Answers (3)

Luca Cappa
Luca Cappa

Reputation: 1999

TL;DR

When developing a custom task based on PowerShell:

  • The PowerShell script should return 0 when it accomplished its job, disrespectful the result is positive or negative.
  • It must return a value different than 0 when the task was unable to properly complete (e.g. infrastructural issue, syntax error, or unexpected exception, and so forth).
  • When the task's job completes, failure or success must always be communicated with the Write-VstsSetResult API of VSTS Task Lib SDK (or the ##vso[task.complete] command).


Details: the vsts-agent starts the PowerShell scripts using C# classes so called 'Handlers', that you specify in the 'execute' section of the 'task.json' file; possible PS based handlers are:

  • PowerShell3
  • PowerShell
  • PowerShellExe

The 'PowerShell3' (or the deprecated 'PowerShell') handler:

  • must be used when creating custom task based on PowerShell; this means that your task is bundled with at least one PS script that is specified in the task.json in the 'execute' section;

  • expects an exit code equal to 0 whatever the result of the task is (ok or fail);

  • expects a value different than 0 when there is an internal error during the script execution, that means the script has been unable to fully completes its job, i.e. when the result of the job of the task is not even known. In short the exit code is irrespective of the positive/negative result of the job of task. When the job is completed (whether negatively or positively) the exit code must be 0. The requirement of an exit code equal to 0 is stated:

    • in the logic of the code;
    • in the comment, where it explicitly states that a task failure should be indicated on standard output by using commands mentioned above;

This is also clear in the build summary where you clutter the build summary when returning exit code different than 0 (for example when using the [Environment]::Exit(1), as shown in the red boxes). Instead you get a clean build summary when exiting gracefully a failing task with 0 exit code and setting the result with Write-VstsSetResult API (green boxes). example of build result with and without using the VSTS TaskLib SDK

Instead the 'PowerShellExe' handler executes a PowerShell script provided by the end user: in this case this handler follows the ordinary rule that ordinary command subdue, that is: - a result status equal to 0 to indicate successful execution; - a result different than 0 to indicate failure of the execution;


Further Details:

When developing a custom task based on PowerShell leveraging the VSTS Task SDK functions it is possible to issue some commands to the agent. One of them is to tell the result (either success of failure) of the execution of the task: this can be done by calling the API function Write-VstsSetResult

Otherwise if the SDK could not be used it is possible anyway to print on the standard output the following command:

##vso[task.complete result=Succeeded|SucceededWithIssues|Failed|Cancelled|Skipped]

which is the same command used underneath by the Write-VstsSetResult function.

The agent indeed intercepts and consumes the standard output of the task, it recognizes the command, and executes it.

When the task has been able to finish its job (whenever this is a failure or a success), it must return exit code 0 and set the result with the aforementioned command. Only when the task was unable to complete its job this must be communicated with an exit code different than 0.

Upvotes: 4

starian chen-MSFT
starian chen-MSFT

Reputation: 33708

Try to use this code instead:

[Environment]::Exit(1)

Upvotes: 1

Peter
Peter

Reputation: 27944

You can add the following line to fail the task:

"##vso[task.complete result=Failed]"

This will tell VSTS that the task failed.

Upvotes: 1

Related Questions