Set-OctopusVariable does NOT set the specified value if its return value is assigned to a variable

Hi,

The attached package contains the code shown under for PreDeploy.ps1 /Deploy.ps1 which reproduces this behavior.
I have absolutely no clue why assigning the return value of the function Set-OctopusVariable to a variable makes it behave differently!?

Thanks
Matthias

PreDeploy.ps1:
@@@
# returns an array with two values
function Main()
{
# this call produces the first value in the returned array, an empty string
Set-OctopusVariable ‘MyVar1’ ‘MyVar1Value’
Write-Host ‘MyVar1=MyVar1Value’
# in order to suppress the value returned by Set-OctopusVariable I want to assign this value to a dummy variable
# doing so results in this value not being propagated to octopus / the deploy.ps1 script
$x = Set-OctopusVariable ‘MyVar2’ ‘MyVar2Value’
Write-Host ‘MyVar2=MyVar2Value’
# this call produces the second value in the returned array
return ‘ReturnValue’
}
$result = Main
# print out all values returned by Main: (result 1 : result 2 : ReturnValue)
$i=0;$result|%{$i+=1;Write-Host ‘result’ $i ': ’ $_}
@@@

Deploy.ps1:
@@@
# prints out ‘MyVar1Value’
Write-Host 'MyVar1: ’ $OctopusParameters[‘MyVar1’]
# prints out nothing!!! WTF?
Write-Host 'MyVar2: ’ $OctopusParameters[‘MyVar2’]
@@@

SetOctopusVariableBug.1.0.4.nupkg (3 KB)

Hi Matthias,

Set-OctopusVariable works like this:

function Encode-ServiceMessageValue([string]$value)
{
    $valueBytes = [System.Text.Encoding]::UTF8.GetBytes($value)
    return [Convert]::ToBase64String($valueBytes)
}
function Set-OctopusVariable([string]$name, [string]$value) 
{ 
    $name = Encode-ServiceMessageValue($name)
    $value = Encode-ServiceMessageValue($value)
Write-Output "##octopus[setVariable name='$name' value='$value']"
}

We process the logs to read those “##octopus[…]” values out.

Since we use Write-Output, when you assign the result to a value, you actually get the output as a string. Since you don’t echo that anywhere, we’re never able to pick it up from the logs.

The workaround for us is to use Write-Host rather than Write-Output which I’m going to do in today’s patch release. But my question to you is, why did you need to assign the value in the first place? What do you need to do with $x?

Paul

Hi Paul,

Well, this really explains it. There was just one missing link: I thought Set-OctopusVariable did just return an empty string because I never ever got my eyes on the ##octopus[setVariable ...]-output because it obviously is being removed from the log! (Which in fact made the observed behavior quite inexplicable)

To answer your question: I was test-deploying my packages using the tentacle commandline and tried to return a hashtable from a function. This function did indirectly contain a couple of calls to Set-OctopusVariable. So instead of returning a hashtable the function seemed to return an array containing an “empty string” for every call to Set-OctopusVariable and the hashtable as the last element.
After fixing that problem by assigning the value returned by Set-OctopusVariable to a dummy powershell variable ($x) i noticed that the new variable values weren’t any longer available in the following deploy scripts.

I wouldn’t call it a workaround to use Write-Host instead of Write-Output. Write-Output does pollute the return value of all functions that directly or indirectly use Set-OctopusVariable so using Write-Host is a much cleaner solution.

Thanks for fixing this issue
Matthias

Thanks for explaining Matthias. The change to Write-Host was included in today’s release.