Не удается обновить переменную в группе библиотек Azure Pipelines из определения выпуска

#powershell #azure-pipelines #azure-pipelines-release-pipeline #azure-pipelines-release-task

#powershell #azure-конвейеры #azure-pipelines-release-pipeline #azure-pipelines-release-task

Вопрос:

У меня есть группа переменных 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
 

Когда я запускаю это из конвейера сборки, все работает так, как задумано — переменная обновляется.

Когда я извлекаю JSON из URI, созданного выше, я получаю следующее:

 {
    "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_temp869a5459-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» уже был отмечен.

введите описание изображения здесь

Итак, что-то явно отличается. Одни и те же строки выдают разные выходные данные в зависимости от того, выполняется ли он из конвейера сборки или конвейера выпуска.

Что я делаю не так?

Я настроил конвейер сборки и этап выпуска точно так же. Я связал группу переменных таким же образом. В «Конвейере выпуска» я настроил область действия ссылки группы переменных на «Этапы -> мой этап». Кажется, все настроено правильно … но это не работает.

Спасибо 🙂

Комментарии:

1. По $oldValue -видимому, это не строка, а a $Null (или не существует в $definition.variables.Version_old.Value ), пожалуйста, поделитесь извлеченным содержимым json ( $definition ).

2. Привет @iRon спасибо за ваш комментарий. Я добавил кучу дополнительной отладочной информации. Я вижу, что метод .Split() завершается с ошибкой из-за нулевого значения. Но я не понимаю, почему скрипт выдает допустимое значение в конвейере сборки и нулевое значение в конвейере выпуска. Спасибо 🙂

Ответ №1:

Я тестирую ваш ps-файл, воспроизводю эту проблему и решаю ее в выпуске. Пожалуйста, проверьте ваше задание на выпуск и убедитесь, что вы установили флажок «Разрешить скриптам доступ к токену OAuth». Прикрепите мой результат теста: введите описание изображения здесь
введите описание изображения здесь

Обновить:

Вы можете попытаться проверить безопасность вашего выпуска, пожалуйста, убедитесь, что вы добавили пользователя службы сборки коллекции проектов в свой выпуск: введите описание изображения здесь

И в безопасности вашей переменной группы вы можете проверить, установлен ли у вас доступ администратора к службе сборки коллекции проектов: введите описание изображения здесь

Кажется, что в выпуске проблема с использованием токена 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
 

Комментарии:

1. Привет @Yujun, я обновил свой пост скриншотом конфигурации задания агента. Флажок уже был установлен. Спасибо 🙂

2. Привет @JesperLundStocholm, я обновил свой ответ, и вы можете найти более подробную информацию ниже Обновления. Пожалуйста, попробуйте проверить и повторите попытку.

3. Привет @Yujun, эти настройки были неправильными в моей настройке. Спасибо!