-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fail on standard error option for azure powershell task #6324
Changes from 14 commits
aa2ead0
691d7a9
1501e39
a4542c6
273d548
2d1516f
8377129
cd1ab79
3655c6f
b597558
8599f04
01e8914
31dcb74
1e74ce5
b95368d
51dd7db
a1c2a47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,8 @@ $scriptType = Get-VstsInput -Name ScriptType -Require | |
$scriptPath = Get-VstsInput -Name ScriptPath | ||
$scriptInline = Get-VstsInput -Name Inline | ||
$scriptArguments = Get-VstsInput -Name ScriptArguments | ||
$__vsts_input_errorActionPreference = Get-VstsInput -Name errorActionPreference | ||
$__vsts_input_failOnStandardError = Get-VstsInput -Name FailOnStandardError | ||
$targetAzurePs = Get-VstsInput -Name TargetAzurePs | ||
$customTargetAzurePs = Get-VstsInput -Name CustomTargetAzurePs | ||
|
||
|
@@ -75,10 +77,11 @@ Update-PSModulePathForHostedAgent -targetAzurePs $targetAzurePs -authScheme $aut | |
try { | ||
# Initialize Azure. | ||
Import-Module $PSScriptRoot\ps_modules\VstsAzureHelpers_ | ||
Initialize-Azure -azurePsVersion $targetAzurePs | ||
Initialize-Azure -azurePsVersion $targetAzurePs -strict | ||
# Trace the expression as it will be invoked. | ||
$__vstsAzPSInlineScriptPath = $null | ||
If ($scriptType -eq "InlineScript") { | ||
$scriptArguments = $null | ||
$__vstsAzPSInlineScriptPath = [System.IO.Path]::Combine(([System.IO.Path]::GetTempPath()), ([guid]::NewGuid().ToString() + ".ps1")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we be using Agent.TempDirectory instead of users temp path? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will update There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
($scriptInline | Out-File $__vstsAzPSInlineScriptPath) | ||
$scriptPath = $__vstsAzPSInlineScriptPath | ||
|
@@ -118,20 +121,33 @@ try { | |
# 2) The task result needs to be set to failed if an error record is encountered. | ||
# As mentioned above, the requirement to handle this is an implication of changing | ||
# the error action preference. | ||
([scriptblock]::Create($scriptCommand)) | | ||
([scriptblock]::Create($scriptCommand)) | | ||
ForEach-Object { | ||
Remove-Variable -Name scriptCommand | ||
Write-Host "##[command]$_" | ||
. $_ 2>&1 | ||
} | | ||
} | | ||
ForEach-Object { | ||
# Put the object back into the pipeline. When doing this, the object needs | ||
# to be wrapped in an array to prevent unraveling. | ||
,$_ | ||
|
||
# Set the task result to failed if the object is an error record. | ||
if ($_ -is [System.Management.Automation.ErrorRecord]) { | ||
"##vso[task.complete result=Failed]" | ||
if($_ -is [System.Management.Automation.ErrorRecord]) { | ||
if($_.FullyQualifiedErrorId -eq "NativeCommandError" -or $_.FullyQualifiedErrorId -eq "NativeCommandErrorMessage") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this errorId localizable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No |
||
,$_ | ||
if($__vsts_input_failOnStandardError -eq $true) { | ||
"##vso[task.complete result=Failed]" | ||
} | ||
} | ||
else { | ||
if($__vsts_input_errorActionPreference -eq "continue") { | ||
,$_ | ||
if($__vsts_input_failOnStandardError -eq $true) { | ||
"##vso[task.complete result=Failed]" | ||
} | ||
} | ||
elseif($__vsts_input_errorActionPreference -eq "stop") { | ||
throw $_ | ||
} | ||
} | ||
} else { | ||
,$_ | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[CmdletBinding()] | ||
param() | ||
|
||
# Arrange. | ||
. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 | ||
$targetAzurePs = "4.1.0" | ||
Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require | ||
Register-Mock Get-VstsInput { "$PSScriptRoot/RedirectsErrors_TargetScript.ps1" } -- -Name ScriptPath | ||
Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs | ||
Register-Mock Get-VstsInput { "continue" } -- -Name errorActionPreference | ||
Register-Mock Get-VstsInput { $false } -- -Name FailOnStandardError | ||
Register-Mock Update-PSModulePathForHostedAgent | ||
Register-Mock Initialize-Azure | ||
|
||
# Act. | ||
$actual = @( & $PSScriptRoot\..\AzurePowerShell.ps1 ) | ||
$global:ErrorActionPreference = 'Stop' # Reset to stop. | ||
|
||
# Assert. | ||
Assert-AreEqual 4 $actual.Length | ||
Assert-AreEqual 'Some output 1' $actual[0] | ||
Assert-AreEqual 'Some error 1' $actual[1].Exception.Message | ||
Assert-AreEqual 'Some output 2' $actual[2] | ||
Assert-AreEqual 'Some error 2' $actual[3].Exception.Message |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[CmdletBinding()] | ||
param() | ||
|
||
# Arrange. | ||
. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 | ||
$targetAzurePs = "4.1.0" | ||
Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require | ||
Register-Mock Get-VstsInput { "$PSScriptRoot/NativeCommandError_TargetScript.ps1" } -- -Name ScriptPath | ||
Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs | ||
Register-Mock Get-VstsInput { "stop" } -- -Name errorActionPreference | ||
Register-Mock Get-VstsInput { $false } -- -Name FailOnStandardError | ||
Register-Mock Update-PSModulePathForHostedAgent | ||
Register-Mock Initialize-Azure | ||
|
||
# Act. | ||
$actual = @( & $PSScriptRoot\..\AzurePowerShell.ps1 ) | ||
$global:ErrorActionPreference = 'Stop' # Reset to stop. | ||
|
||
# Assert. | ||
Assert-AreEqual 4 $actual.Length | ||
Assert-AreEqual 'output 1' $actual[0] | ||
Assert-AreEqual 'NativeCommandError' $actual[1].FullyQualifiedErrorId | ||
Assert-AreEqual 'NativeCommandErrorMessage' $actual[2].FullyQualifiedErrorId | ||
Assert-AreEqual 'output 2' $actual[3] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[CmdletBinding()] | ||
param() | ||
|
||
# Arrange. | ||
. $PSScriptRoot\..\..\..\Tests\lib\Initialize-Test.ps1 | ||
$targetAzurePs = "4.1.0" | ||
Register-Mock Get-VstsInput { "FilePath" } -- -Name ScriptType -Require | ||
Register-Mock Get-VstsInput { "$PSScriptRoot/NativeCommandError_TargetScript.ps1" } -- -Name ScriptPath | ||
Register-Mock Get-VstsInput { $targetAzurePs } -- -Name TargetAzurePs | ||
Register-Mock Get-VstsInput { "silentlyContinue" } -- -Name errorActionPreference | ||
Register-Mock Get-VstsInput { $true } -- -Name FailOnStandardError | ||
Register-Mock Update-PSModulePathForHostedAgent | ||
Register-Mock Initialize-Azure | ||
|
||
# Act. | ||
$actual = @( & $PSScriptRoot\..\AzurePowerShell.ps1 ) | ||
$global:ErrorActionPreference = 'Stop' # Reset to stop. | ||
|
||
# Assert. | ||
Assert-AreEqual 6 $actual.Length | ||
Assert-AreEqual 'output 1' $actual[0] | ||
Assert-AreEqual 'NativeCommandError' $actual[1].FullyQualifiedErrorId | ||
Assert-AreEqual '##vso[task.complete result=Failed]' $actual[2] | ||
Assert-AreEqual 'NativeCommandErrorMessage' $actual[3].FullyQualifiedErrorId | ||
Assert-AreEqual '##vso[task.complete result=Failed]' $actual[4] | ||
Assert-AreEqual 'output 2' $actual[5] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Write-Output "output 1" | ||
net user foobar | ||
Write-Output "output 2" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,14 +15,22 @@ | |
], | ||
"author": "Microsoft Corporation", | ||
"version": { | ||
"Major": 2, | ||
"Major": 3, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add "releaseNotes" attribute to call out what is changed in this major version. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
"Minor": 0, | ||
"Patch": 7 | ||
"Patch": 2 | ||
}, | ||
"demands": [ | ||
"azureps" | ||
], | ||
"minimumAgentVersion": "1.95.0", | ||
"preview": true, | ||
"groups": [ | ||
{ | ||
"name": "AzurePowerShellVersionOptions", | ||
"displayName": "Azure PowerShell version options", | ||
"isExpanded": true | ||
} | ||
], | ||
"minimumAgentVersion": "2.0.0", | ||
"inputs": [ | ||
{ | ||
"name": "ConnectedServiceNameSelector", | ||
|
@@ -59,9 +67,9 @@ | |
}, | ||
{ | ||
"name": "ScriptType", | ||
"type": "pickList", | ||
"type": "radio", | ||
"label": "Script Type", | ||
"required": true, | ||
"required": false, | ||
"helpMarkDown": "Type of the script: File Path or Inline Script", | ||
"defaultValue": "FilePath", | ||
"options": { | ||
|
@@ -97,23 +105,46 @@ | |
"type": "string", | ||
"label": "Script Arguments", | ||
"defaultValue": "", | ||
"visibleRule": "ScriptType = FilePath", | ||
"required": false, | ||
"properties": { | ||
"editorExtension": "ms.vss-services-azure.parameters-grid" | ||
}, | ||
"helpMarkDown": "Additional parameters to pass to PowerShell. Can be either ordinal or named parameters." | ||
}, | ||
{ | ||
"name": "errorActionPreference", | ||
"type": "pickList", | ||
"label": "ErrorActionPreference", | ||
"required": false, | ||
"defaultValue": "stop", | ||
"options": { | ||
"stop": "Stop", | ||
"continue": "Continue", | ||
"silentlyContinue": "SilentlyContinue" | ||
}, | ||
"helpMarkDown": "Select the value of the ErrorActionPreference variable for executing the script." | ||
}, | ||
{ | ||
"name": "FailOnStandardError", | ||
"type": "boolean", | ||
"label": "Fail on Standard Error", | ||
"required": false, | ||
"defaultValue": "false", | ||
"helpMarkDown": "If this is true, this task will fail if any errors are written to the error pipeline, or if any data is written to the Standard Error stream." | ||
}, | ||
{ | ||
"name": "TargetAzurePs", | ||
"aliases": ["azurePowerShellVersion"], | ||
"type": "pickList", | ||
"type": "radio", | ||
"label": "Azure PowerShell Version", | ||
"defaultValue": "OtherVersion", | ||
"required": false, | ||
"options": { | ||
"LatestVersion": "Latest installed version", | ||
"OtherVersion": "Specify other version" | ||
}, | ||
"groupName": "AzurePowerShellVersionOptions", | ||
"helpMarkDown": "In case of hosted agents, the supported Azure PowerShell Versions are: 2.1.0, 3.8.0, 4.2.1 and 5.1.1(Hosted VS2017 Queue), 3.6.0(Hosted Queue).\nTo pick the latest version available on the agent, select \"Latest installed version\".\n\nFor private agents you can specify preferred version of Azure PowerShell using \"Specify version\"" | ||
}, | ||
{ | ||
|
@@ -124,6 +155,7 @@ | |
"defaultValue": "", | ||
"required": true, | ||
"visibleRule": "TargetAzurePs = OtherVersion", | ||
"groupName": "AzurePowerShellVersionOptions", | ||
"helpMarkDown": "Preferred Azure PowerShell Version needs to be a proper semantic version eg. 1.2.3. Regex like 2.\\*,2.3.\\* is not supported. The Hosted VS2017 Pool currently supports versions: 2.1.0, 3.8.0, 4.2.1, 5.1.1" | ||
} | ||
], | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why have a different naming convention just for these inputs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
erroractionpreference is a well known name. the other reason is that we remove the variables and functions from the current scope before executing the script, but we cannot remove these variables since we need them as the script is executing. And so, to avoid a conflict between these names and similar names defined in the user script, we use this scheme.