Оговорюсь, что основные примеры будут на Release Pipelines, потому, что YAML туда еще не доехал, а мне нужна функциональность множества этапов и множества артефактов. Это, вроде стало доступно в обынчых Pipelines, что практически уровняло их по функциональности. В Pipelines YAML допилили и добавили к текстовому представлению, небольшую графическую подсказку с параметрами, которые можно задать. Очень удобно, не надо лезть в документацию по каждому модулю. Но это буду описывать в следующей статье, пока вот картинка самого нововведения.

Хранение и использование
Начнем с того, что в системе у нас есть переменные по умолчанию. Они начинаются, в зависимости от происхождения со слов Release, System, etc. Полный список (как оказалось, нет), доступен в документации. Всю шизофрению с синтаксисом иллюстрирует пример из документации ниже. У одной и той же переменной есть три представления, в зависимости от того, где мы ее вызываем.
steps:
- bash: echo This script could use $SYSTEM_ACCESSTOKEN
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- powershell: Write-Host "This is a script that could use $env:SYSTEM_ACCESSTOKEN"
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Если вы задаете переменную на агенте, котором исполняется таск это $(System.AccessToken). Если вы хотите использовать ее внутри powershell скрипта на том же агенте, это уже будет $env:SYSTEM_ACCESSTOKEN. Если вы, упаси бог, хотите использовать эту переменную на каком то удаленном хосте, используя таск PowerShell on target machines, вам нужно передать это через аргумент к скрипту, используя param. С bash попроще, можно просто прокидывать внутрь используя аргумент и синтаксис $SYSTEM_ACCESSTOKEN.
Те же законы не распростроняются на ваши собственные переменные, тут уже вы несете ответственность за синтаксис. Задать переменные можно локально в каждой задаче.

Глобально в хранилище переменных и линковать их из хранилища. Очень удобно.

Бонусом к этому, если переменные шибко секретные, их можно хранить в облаке Azure в хранилище переменных под названием Azure Vault, залинковать хранилище к переменным проекта можно в Library.

В целом с переменными все понятно, в pipelines их еще можно задавать в ручную на каждый запуск, в release такой функциональности нет. Посмотреть что вы передаете в пайплайн можно еще раз в логах инициализации агента, но учтите, они там уже в преобразованном виде.

Динамические переменные
Самое интересное начинается, когда мы хотим получить некоторое значение в одном этапе и передать его в следующий.

Такой функциональности нам не завезли. Но наши руки не для скуки и при помощи гугла было найдено решение. Слава богу у Azure DevOps есть API, который нам позволяет сделать чуть больше, чем нарисовали в интерфейсе.
Итак, нам понадобится вызов по обновлению глобальных переменных, который мы будем делать прямо изнутри пайплайна. Адрес берется из переменных, тех самых о которых нет ни слова в документации, как упоминалось ранее. Вы можете их самостоятельно задать или, что уж там, захардкодить, если лавочку прикроют.
$releaseurl = ('{0}{1}/_apis/release/releases/{2}?api-version=5.0' -f $($env:SYSTEM_TEAMFOUNDATIONSERVERURI), $($env:SYSTEM_TEAMPROJECTID), $($env:RELEASE_RELEASEID) )
Задаем пустое значение переменной, которую мы хотим передать, ставим Scope — Release

Для примера делаем некоторый рандомный генератор переменных. Обратите внимание на синтаксис объявления переменной внутри этого этапа, такой функционал завезли.

В следующем этапе мы передаем переменную скрипту, да да, напрямую нельзя, надо через параметр.

Скрипт powershell под спойлером
#Script requires stageVar variable in release variables set to Release scope param ( [string] $expVar ) #region variables $ReleaseVariableName = 'StageVar' $releaseurl = ('{0}{1}/_apis/release/releases/{2}?api-version=5.0' -f $($env:SYSTEM_TEAMFOUNDATIONSERVERURI), $($env:SYSTEM_TEAMPROJECTID), $($env:RELEASE_RELEASEID) ) #endregion #region Get Release Definition Write-Host "URL: $releaseurl" $Release = Invoke-RestMethod -Uri $releaseurl -Headers @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } #endregion #region Output current Release Pipeline Write-Output ('Release Pipeline variables output: {0}' -f $($Release.variables | ConvertTo-Json -Depth 10)) #endregion #region Update StageVar with new value $release.variables.($ReleaseVariableName).value = "$expVar" #endregion #region update release pipeline Write-Output ('Updating Release Definition') $json = @($release) | ConvertTo-Json -Depth 99 Invoke-RestMethod -Uri $releaseurl -Method Put -Body $json -ContentType "application/json" -Headers @{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } #endregion #region Get updated Release Definition Write-Output ('Get updated Release Definition') Write-Host "URL: $releaseurl" $Release = Invoke-RestMethod -Uri $releaseurl -Headers @{ Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN" } #endregion #region Output Updated Release Pipeline Write-Output ('Updated Release Pipeline variables output: {0}' -f $($Release.variables | ConvertTo-Json -Depth 10)) #endregion
Вариант для bash
INPUT_VAR=$1 RELEASE_VAR=$2 echo Test ID: ${INPUT_VAR} RELEASE_URL="${SYSTEM_TEAMFOUNDATIONSERVERURI}${SYSTEM_TEAMPROJECTID}/_apis/release/releases/${RELEASE_RELEASEID}?api-version=5.0" echo release url: $RELEASE_URL RELEASE_JSON=$(curl -H "Authorization: Bearer $SYSTEM_ACCESSTOKEN" $RELEASE_URL) OUTPUT=`jq ''.variables.${RELEASE_VAR}.value' = '\"${INPUT_VAR}\"'' <<< $RELEASE_JSON` curl -H "Authorization: Bearer $SYSTEM_ACCESSTOKEN" -H "Content-Type: application/json" -X PUT -d "$OUTPUT" $RELEASE_URL
В двух словах наш скрипт берет на входе переменную myVar и используя API кладет значение этой переменной в stageVar. В следующем этапе, используя синтаксис системных переменных, мы можем ее посмотреть.

Пример довольно простой, но функционал открывает нам хорошие возможности в сумме с моей прошлой статьей, когда мы можем создать виртуальную машину на первом этапе тестирования, проделать с ней какие-то манипуляции дальше, причем параллельно несколько. И финальным этапом ее уничтожить. Сейчас у нас гоняются автотесты кода каждый раз на свежих виртуалках таким образом. А учитывая что живут они минут 10, стоит это копейки.
В следующей статье, если будет необходимость, расскажу о YAML пайплайнах, там довольно много интересных нововведений последнее время.
ссылка на оригинал статьи https://habr.com/ru/post/491444/
Добавить комментарий