Modules/businessdev.ALbuild.Pipeline/Private/Invoke-AdoTaskStep.ps1
|
function Invoke-AdoTaskStep { <# .SYNOPSIS Runs a single extension task (task.ps1) the way the Azure DevOps agent would, locally. .DESCRIPTION Internal helper for the local pipeline runner. Sets the task's INPUT_* environment variables (and any step-level env), runs task.ps1 in a child PowerShell process, echoes its output, and captures "##vso[task.setvariable ...]" commands back into the runtime variables so later steps can read them via $(var). The INPUT_* variables are removed again after the step so they do not leak into the next one. .PARAMETER TaskScript Path to the task.ps1 to run. .PARAMETER Inputs The task inputs (name -> already-expanded value). .PARAMETER StepEnv Step-level environment variables (name -> already-expanded value). .PARAMETER Variables The runtime variable map (case-insensitive); updated in place from set-variable commands. .PARAMETER PowerShellExe The PowerShell executable to launch the task with. .OUTPUTS PSCustomObject (Success, ExitCode). #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [string] $TaskScript, [hashtable] $Inputs = @{}, [hashtable] $StepEnv = @{}, [Parameter(Mandatory)] [hashtable] $Variables, [Parameter(Mandatory)] [string] $PowerShellExe ) $applied = [System.Collections.Generic.List[string]]::new() try { foreach ($key in $Inputs.Keys) { $envName = "INPUT_$($key.ToUpperInvariant())" Set-Item -Path "Env:$envName" -Value "$($Inputs[$key])" $applied.Add($envName) } foreach ($key in $StepEnv.Keys) { Set-Item -Path "Env:$key" -Value "$($StepEnv[$key])" $applied.Add($key) } $result = Invoke-ALbuildProcess -FilePath $PowerShellExe ` -Arguments @('-NoProfile', '-NonInteractive', '-File', $TaskScript) -PassThru -RetryCount 0 -StreamOutput } finally { foreach ($envName in $applied) { Remove-Item -Path "Env:$envName" -ErrorAction SilentlyContinue } } # Output was already echoed live by -StreamOutput; here we only harvest set-variable commands. if ($result.StdOut) { foreach ($line in ($result.StdOut -split "`r?`n")) { $command = ConvertFrom-VsoCommand -Line $line if ($command) { $Variables[$command.Name] = $command.Value } } } # Surface the failure reason readably: a failed task.ps1 prints PowerShell's full error-view # (source line, '~~~~', 'At line:', '+ CategoryInfo'/'+ FullyQualifiedErrorId') to stderr; reduce # it to the core message so the build log shows why it failed, not a raw error dump. if ($result.StdErr -and -not $result.Success) { $message = Format-BcErrorMessage -Text $result.StdErr if ($message) { Write-ALbuildLog -Level Error $message.Trim() } } return [PSCustomObject]@{ Success = $result.Success; ExitCode = $result.ExitCode } } |