0

我有一个 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 令牌”已被勾选。

在此处输入图像描述

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

我做错了什么?

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

谢谢 :-)

4

1 回答 1

1

我测试了你的 ps 文件,然后我重现了这个问题并在 Release 中解决了它。请检查您的发布作业并确保您已选中“允许脚本访问 OAuth 令牌”。附上我的测试结果: 在此处输入图像描述 在此处输入图像描述

更新:

您可以尝试检查您的发布安全性,请确保您已将项目集合构建服务用户添加到您的发布中: 在此处输入图像描述

在您的变量组安全性中,您可以检查您是否设置了项目集合构建服务用户管理员访问权限: 在此处输入图像描述

您的问题似乎与发行版中的 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
于 2021-03-15T09:35:38.073 回答