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

问题描述

我有一个 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

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

从上面创建的 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\_temp\869a5459-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 令牌”。

enter image description here

所以显然有些不同。 完全相同的行产生不同的输出,具体取决于它是从构建管道还是发布管道运行。

我做错了什么?

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

谢谢:-)

解决方法

我测试了你的 ps 文件,我重现了这个问题并在 Release 中解决了它。请检查您的发布作业并确保您已选中“允许脚本访问 OAuth 令牌”。附上我的测试结果: enter image description here enter image description here

更新:

您可以尝试检查您的发布安全性,请确保您已将项目集合构建服务用户添加到您的发布中: enter image description here

并且在您的变量组安全性中,您可以检查您是否设置了项目集合构建服务用户管理员访问权限: enter image description here

您的问题似乎与发行版中的 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