Octopus部署流程:步骤间共享数据

Octopus deploy process: share data between steps

给定一个 runbook/process 有 3 个步骤

Set-OctopusVariable -name "SharedData" -value ($sharedObject | ConvertTo-Json)
$OctopusParameters["Octopus.Action[StepA].Output.SharedData"]
$OctopusParameters["Octopus.Action[StepB].Output.SharedData"]

假设任何次级步骤都可以使用来自任何先前步骤的共享数据对象。它只是一个对象,沿途经过多个步骤操作。

如果我选择跳过步骤 2,那么步骤 3 将看不到步骤 2 的输出 var 值,因为读取指令需要步骤的名称(StepAStepB)。

有没有办法让输出 var read 语法只从上一步而不是明确命名的步骤中获取值?例如:

$OctopusParameters["Octopus.Action[previous step alias].Output.SharedData"]

我已经尝试过直接使用 $OctopusParameters 字典来做到这一点。

一步到位:

$OctopusParameters["SharedData"] = ($sharedObject | ConvertTo-Json)

然后在后续步骤中:

$sharedObject = $OctopusParameters["SharedData"] | ConvertFrom-Json

但它不起作用。字典读 returns 为空。原始字典分配不会在步骤之间保留。它只能使用提供的 Set-OctopusVariable 帮助程序或其他规定的方法来工作,但这些方法会使您无法知道上一步的名称。

或者,有没有一种方法可以将数据更“全局”地存储到流程执行中供以后使用,而无需将其特定于流程的另一个步骤的输出?

您可以根据是否跳过 StepB 将其包装在条件中,例如

#{if Octopus.Action[StepB].IsSkipped}
$OctopusParameters["Octopus.Action[StepA].Output.SharedData"]
#{else}
$OctopusParameters["Octopus.Action[StepB].Output.SharedData"]
#{/if}

我解决这个问题的方法是考虑使用字典 $OctopusParameters 对您有利。因为它是一本字典,所以它具有您可以检查的键。如果想得到最后一个同名变量,只需要遍历key,得到最后一个。

例如,假设您有一个这样的部署过程:

步骤 A 有这样的代码:

$sharedObject = [PSCustomObject]@{
    StepName = "Step A";
    Value = "Value from Step A";
    Message = "Step A says Hello!";
};

Set-OctopusVariable -name "SharedData" -value ($sharedObject | ConvertTo-Json)

虽然 步骤 B 有这样的代码:

$sharedObject = [PSCustomObject]@{
    StepName = "Step B";
    Value = "Value from Step B";
    Message = "Step B says Hello!";
};

Set-OctopusVariable -name "SharedData" -value ($sharedObject | ConvertTo-Json)

最后,最后一步检查是否存在任何以 SharedData 结尾的输出变量,然后遍历每个变量以将值打印到日志中。

然后选择最后一个,这是重要的部分。它这样做是为了无论跳过步骤 A 或步骤 B 中的哪一个,它总是会获得设置变量的最后一个(您显然可以更改此逻辑以满足您的要求)

$MatchingKeys = $OctopusParameters.Keys | Where-Object { $_ -match "^Octopus\.Action.*\.Output.SharedData$" }
Write-Highlight "Found $($MatchingKeys.Count) matching output variables"

foreach($matchingKey in $matchingKeys) {
    $OutputVariableValue = $OctopusParameters[$matchingKey]
    
    Write-Host "$matchingKey value: $OutputVariableValue"
}

Write-Host "Finding last value..."
$lastKey = $matchingKeys | Select-Object -Last 1

Write-Highlight "Last Match: $($OctopusParameters[$lastKey])"

你也可以把上面的变成one-liner:

$JsonSharedData = $($OctopusParameters.Keys | Where-Object { $_ -match "^Octopus\.Action.*\.Output.SharedData$" } | Select-Object -Last 1 | ForEach-Object {$OctopusParameters[$_]})