We continue the review of the wonderful tool for Windows development and beyond, Azure DevOps. This time, having struggled with environment variables, I decided to share all my experience in one article.
Starting from the fact that they have different syntax for each runtime environment, to the lack of a standard way to transfer variables from one stage of the pipeline to another.
I should note that the main examples will be on Release Pipelines, because YAML hasnāt arrived there yet, and I need the functionality of multiple stages and multiple artifacts. This seems to have become available in regular Pipelines, which almost equalized their functionality. In YAML Pipelines, enhancements have been made, and a small graphical hint with parameters that can be set has been added to the text representation. Very convenient, no need to dig into the documentation for each module. But I will describe this in the next article, for now hereās an image of the feature.

Storage and usage
Letās start with the fact that we have default variables in the system. They begin, depending on their origin, with the words Release, System, etc. The complete list (as it turned out, there isn't one), is available in . The entire schizophrenia with syntax is illustrated by the example from the documentation below. The same variable has three representations, depending on where we call it.
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)If you set a variable on the agent on which the task is executed, itās $(System.AccessToken). If you want to use it inside a PowerShell script on the same agent, it will be $env:SYSTEM_ACCESSTOKEN. If, God forbid, you want to use this variable on some remote host, using the PowerShell task on target machines, you need to pass it through an argument to the script, using . With bash, it's simpler; you can just pass it using an argument and the syntax $SYSTEM_ACCESSTOKEN.
The same rules do not apply to your own variables; you bear responsibility for the syntax. You can set variables locally in each task.

Or globally in the variable store, and then link them from the store. Very convenient.

Als bonus kun je, als de variabelen te geheim zijn, deze opslaan in de Azure cloud in een opslag die Azure Vault heet. De Vault kan aan het project worden gekoppeld in de Bibliotheek.

Over het algemeen is het met variabelen duidelijk. In pipelines kunnen ze handmatig voor elke run worden ingesteld; in release is deze functionaliteit er niet. Wat je in de pipeline doorgeeft, kun je nogmaals bekijken in de logboeken van de agentinitialisatie, maar houd er rekening mee dat ze daar al in een omgevormde toestand staan.

Dynamische variabelen
Het meest interessante begint wanneer we een bepaalde waarde in ƩƩn fase willen ontvangen en deze naar de volgende willen doorgeven.

Die functionaliteit hebben ze ons niet gegeven. Maar onze handen zijn niet voor niets en met behulp van Google is er een oplossing gevonden. Gelukkig heeft Azure DevOps een API die ons iets meer laat doen dan wat er in de interface is getekend.
Dus we hebben een aanroep nodig voor het bijwerken van globale variabelen, die we rechtstreeks vanuit de pipeline gaan doen. Het adres wordt gehaald uit omgevingsvariabelen, die in de documentatie niet worden genoemd, zoals eerder vermeld. Je kunt ze zelf instellen of, als je wilt, hardcoderen als de mogelijkheid wordt gesloten.
$releaseurl = ('{0}{1}\/ _apis\/release\/releases\/{2}?api-version=5.0' -f $($env:SYSTEM_TEAMFOUNDATIONSERVERURI), $($env:SYSTEM_TEAMPROJECTID), $($env:RELEASE_RELEASEID))We stellen een lege waarde in voor de variabele die we willen doorgeven, met Scope ā Release.

Als voorbeeld maken we een willekeurige waardengenerator. Let op de syntaxis voor het declareren van een variabele binnen deze fase; die functionaliteit is toegevoegd.

In de volgende stap geven we de variabele door aan het script; ja, het kan niet rechtstreeks, het moet via een argument.

Script onder de spoiler.
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))
#endregionOf
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_URLIn het kort, ons script neemt de ingangsvariabele myVar en stelt met de API de waarde van deze variabele in stageVar in. In de volgende fase kunnen we deze bekijken met de syntaxis van systeemvariabelen.

Het voorbeeld is vrij eenvoudig, maar de functionaliteit opent ons goede mogelijkheden, samen met mijn eerdere. , wanneer we een virtuele machine kunnen creƫren in de eerste fase van de test, kunnen we er vervolgens verschillende handelingen mee uitvoeren, zelfs parallel. En als eindfase vernietigen we deze. Momenteel worden productautomatiseringstests elke keer uitgevoerd op nieuwe virtuele machines. Aangezien ze slechts 10 minuten meegaan, kost dat bijna niets.
In het volgende artikel, als er behoefte aan is, zal ik vertellen over YAML-pijplijnen, daar zijn de laatste tijd best veel interessante vernieuwingen in.
Bron: habr.com
