无法根据发布定义更新 Azure Pipelines 库组中的变量

Cannot update variable in Azure Pipelines Library group from Release definition

我有一个 Azure Pipelines 变量组,其中包含在“库”中定义的树变量。我想更新管道中的一个值。

我为此编写了这个 Powershell 脚本。

$variableName = "Version_old"
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/distributedtask/variablegroups/4?api-version=5.1-preview.1"

$authHeader = @{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
$definition = Invoke-RestMethod -Uri $url -Headers $authHeader

$oldValue = $definition.variables.$variableName.Value
Write-Host "Using old value:" $oldValue

$array = $oldValue.Split(".")
$newValue = $array[0] + "." + $array[1]+"." +  ([int] $array[2] + 1) 
Write-Host "Updating new value:" $newValue

$definition.variables.$variableName.Value = "$($newValue)"
$definitionJson = $definition | ConvertTo-Json -Depth 100 -Compress
Invoke-RestMethod -Method Put -Uri $url -Headers $authHeader -ContentType "application/json" -Body ([System.Text.Encoding]::UTF8.GetBytes($definitionJson)) | Out-Null

当我从构建管道 运行 执行此操作时,一切都按预期工作 - 变量已更新。

I 从上面创建的 URI 中提取 JSON 时,我得到这个:

{
    "createdBy": {
        "displayName": "<redacted>",
        "id": "guid",
        "uniqueName": "<redacted>"
    },
    "createdOn": "2020-12-16T02:21:48.65Z",
    "id": 4,
    "isShared": false,
    "modifiedBy": {
        "displayName": "MyTeam Build Service (myorg)",
        "id": "<redacted>",
        "uniqueName": "Build\<redacted>"
    },
    "modifiedOn": "2021-03-14T19:55:34.1466667Z",
    "name": "MyTeam",
    "type": "Vsts",
    "variableGroupProjectReferences": [
        {
            "name": "MyTeam",
            "projectReference": {
                "id": "<redacted>",
                "name": "MyTeam"
            }
        }
    ],
    "variables": {
        "API": {
            "value": "0.8.8"
        },
        "UI": {
            "value": "0.7.13"
        },
        "Version_old": {
            "value": "10.0.19"
        }
    }
}

但是 - 当我逐字复制脚本并将其添加为发布管道中的任务时,它失败了。

当我将这些行添加到脚本时

Write-Host "JSON content from REST API:"
Write-Host $definition.variables.API.value
Write-Host $definition.variables.UI.value
Write-Host $definition.variables.Version_old.value

构建管道中的结果是这样的:

2021-03-14T21:15:35.8686524Z JSON content from REST API:
2021-03-14T21:15:35.8769811Z 0.8.9
2021-03-14T21:15:35.8828202Z 0.7.13
2021-03-14T21:15:35.8863094Z 10.0.22
2021-03-14T21:15:35.8912583Z Using old value: 10.0.22
2021-03-14T21:15:35.9233459Z Updating new value: 10.0.23

但这在发布管道中:

2021-03-14T21:17:42.7708488Z JSON content from REST API:
2021-03-14T21:17:42.7833228Z 
2021-03-14T21:17:42.7863873Z 
2021-03-14T21:17:42.7890923Z 
2021-03-14T21:17:42.7954203Z Using old value: 
2021-03-14T21:17:42.9884159Z You cannot call a method on a null-valued expression.
2021-03-14T21:17:42.9885985Z At C:\agent\_work\_temp9a5459-3622-464a-9f6e-f20fb6ac1020.ps1:20 char:1
2021-03-14T21:17:42.9886600Z + $array = $oldValue.Split(".")

(我没有加三个或多或少的空行)

更多调试信息:

当我修改脚本以将 $definition 变量通过管道传输到输出时,如下所示:

$definition = Invoke-RestMethod -Uri $url -Headers $authHeader
Write-Host "JSON content from REST API:"
Write-Host $definition

这是我的构建管道的结果:

2021-03-14T21:28:25.5046100Z JSON content from REST API:
2021-03-14T21:28:25.5109539Z @{variables=; id=4; type=Vsts; name=MyTeam; createdBy=; createdOn=2020-12-16T02:21:48.65Z; modifiedBy=; modifiedOn=2021-03-14T21:15:35.96Z; isShared=False; variableGroupProjectReferences=System.Object[]}

这是我发布管道的结果:

2021-03-14T21:31:50.5474731Z JSON content from REST API:
2021-03-14T21:31:50.5478033Z @{id=4; name=MyTeam; isShared=False; variableGroupProjectReferences=}

发布作业的配置:

我的配置是这样的。 “允许脚本访问 OAuth 令牌”已被勾选。

所以有些东西明显不同了。 exact 相同的行产生不同的输出,具体取决于它是来自构建管道还是发布管道的 运行。

我做错了什么?

我已经配置了完全相同的构建管道和发布阶段。我用同样的方法 link 编辑了变量组。在“发布管道”中,我已将变量组 link 的范围配置为“阶段 --> 我的阶段”。一切似乎都设置正确......但它不起作用。

谢谢 :-)

我测试了你的 ps 文件,我重现了这个问题并在发布中解决了它。请检查您的发布作业并确保您已检查 'Allow scripts to access the OAuth token'。附上我的测试结果:

更新:

您可以尝试检查您的发布安全性,请确保您已将 Project Collection Build Service 用户添加到您的发布中:

并且在你的变量组安全中,你可以检查你是否设置了Project Collection Build Service用户管理员权限:

您的问题似乎与发布中的 OAuth 令牌使用问题有关,因此我们也可以尝试创建一个新的 PAT 令牌并在 PS 脚本中使用它:

$token = "xxxxxxx"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))

$response2 = Invoke-RestMethod -Uri $urlIds -Headers @{Authorization = "Basic $token"} -Method Post -Body $JSON -ContentType application/json