Is there a way to persist changes in environment value between tasks in Visual Studio Team Services? I'm using Powershell to change it but it only changes it in the task not the whole process.
script 1
Write-Verbose "Before: $Env:SuperVersion"
$Env:SuperVersion = $NewVersion
Write-Verbose "After: $Env:SuperVersion"
script 2
Write-Verbose "Final: $Env:SuperVersion"
I see the change at After but Final is always getting the original value
Based on this issue following line will do the trick.
Write-Host ("##vso[task.setvariable variable=SuperVersion;]$NewVersion")
You may find more commands like that in here
Correct answer has already been posted for this question below, however I think that the discussion presented at the following blog specifically targets the two different ways of setting build variables: one in which the variable will be available only within the specific task in which it is set and another using which you can set a build variable in one task and then access it in another:
https://blogs.msdn.microsoft.com/premier_developer/2016/04/13/tips-for-writing-powershell-scripts-to-use-in-build-and-release-tasks/
I find that after using
Write-Host ("##vso[task.setvariable variable=SuperVersion;]$NewVersion")
that within the same task, the value has not changed, but in later tasks that value has changed.
This is on TFS 2018 using inline powershell.
FIRST TASK
$ENV:SuperVersion = "2.0"
Write-Host ("##vso[task.setvariable variable=SuperVersion;]"3.2"")
# Output will be "2.0"
Write-Output $ENV:SuperVersion
$ENV:SuperVersion = "5.5"
# Output will be "5.5" but only within the scope of this task.
Write-Output $ENV:SuperVersion
NEXT TASK
Write-Output $ENV:SuperVersion
# Output is "3.2"
Environment variables created with $env: are Process variables, so they're lost when the process exits and you can't access them from another process (PowerShell instance).
You need to create User or Machine environment variable:
[Environment]::SetEnvironmentVariable('SuperVersion', $NewVersion, 'User')
[Environment]::SetEnvironmentVariable('SuperVersion', $NewVersion, 'Machine')
I'm not sure though, that it will work in VS Team Services, you'd have to test it.
Reference:
Types of environment variables
Reuse of environment variables in Path
Related
I've a Release pipeline in AzureDevops which pulls it's artifact from Azure Container Registry.
By creating a new release, at the "dockerbuild" needs to be selected which image from ACR shall be chosen:
Currently i can't access the variable "dockerbuild" with it's value "1358 in the release pipeline. How do i need to write this, for access from powerShell?
I tried these approaches, without luck:
Try the following,
Write-Host $env:RELEASE_ARTIFACTS_dockerbuild_BUILDNUMBER
You probably already see the reference.
The article of release artifact alias Usage that Charles provided is correct.
But the usage he provided still have problem.
It only works on OS like windows OS which is not case-sensitive.
See the below usage:
Write-Host "$ env:RELEASE_ARTIFACTS_dockerbuild_BUILDNUMBER"
Write-Host $env:RELEASE_ARTIFACTS_dockerbuild_BUILDNUMBER #This only works on windows.
Write-Host "$ env:RELEASE_ARTIFACTS_DOCKERBUILD_BUILDNUMBER"
Write-Host $env:RELEASE_ARTIFACTS_DOCKERBUILD_BUILDNUMBER #This will work both on windows and linux.
Write-Host "$ (Release.Artifacts.dockerbuild.BuildNumber)"
Write-Host $(Release.Artifacts.dockerbuild.BuildNumber) #In Inline script, this will always work.
You can use $(Build.BuildNumber).
In powershell i usually use write-host to print out a variable whilst working in an azuredevops pipeline to check the value of a variable.
Can you do this in terraform? I am running some terraform code but want to check some of the terraform variable values during the pipeline run , is there a way of doing this?
According to documentation :
- pwsh: |
Write-Host "Non-secrets automatically mapped in, sauce is $env:SAUCE"
Write-Host "Secrets are not automatically mapped in, secretSauce is $env:SECRETSAUCE"
Write-Host "You can use macro replacement to get secrets, and they'll be masked in the log: $(secretSauce)"
Write-Host "Future jobs can also see $env:SETVARS_OUTPUTSAUCE"
write-Host "Future jobs can also see $(SetVars.outputSauce)"
Just run terraform plan part of the pipeline to check if the variables are set as expected.
You can also reference variables in terraform output if you need to.
Original question
Is it possible to store the response from a REST API call in a
variable and use it in the downstream jobs?
Question update:
I want to store the resolved value through a PowerShell script, and make it accessible through out the next stages. I have setup a script like this:
$slot = &"c:\temp\GetSlot.exe" 2>&1
Write-host "resolved:" $slot
Write-host "init value output:" $(currentslot)
Write-Output ("##vso[task.setvariable variable=currentslot;isOutput=true;]$slot")
Write-host "updated value output:" $(currentslot)
Along with a variable, to make it accessible throug the $(currentslot) in aditional stages. Its configured like this:
Stages:
The value from the executions is being set into the $slot variable, but the variable is not getting updated, what do I do wrong?
yes, you would use regular way of doing so:
Write-Host "##vso[task.setvariable variable=containerName]$containerName"
^ ^ variable content (string)
^ variable name in downstream tasks
you can also use yaml to share variables between phases (https://github.com/MicrosoftDocs/vsts-docs/blob/master/docs/pipelines/process/multiple-phases.md)
create\update release through api: https://learn.microsoft.com/en-us/rest/api/azure/devops/release/definitions/create?view=azure-devops-rest-5.0 (it has variables property)
I'm using TFS 2017.1 Builds and Release feature.
In my release definition, I have a couple of release variables which I need to refer in my PowerShell task (execute on remote machine). So far, I've tried the following options but couldn't get it to work.
Added an Execute PowerShell task to store release variables into Environment variables:
$releaseVaraiables = Get-ChildItem Env: | Where-Object { $_.Name -like "ACL_*" }
Write-Host "##vso[task.setvariable variable=aclVariables]$releaseVaraiables"
Added an Execute PowerShell on remote machine task:
Here I can't read the Environment variables (maybe because this is remote machine task?)
Write-Verbose "problem reading $env:aclVariables" -Verbose
Then I tried passing the environment variable as an argument, but that didn't work either
param
(
$RbacAccessTokenParams
)
$RbacAccessTokenParams.GetEnumerator() | % {$_.Name}
$RbacAccessTokenParams | % {
Write-Verbose "variable is $_" -Verbose
Write-Verbose "name is $_.Name" -Verbose
Write-Verbose "value is $_.Value" -Verbose
}
This is how I passed as argument
-RbacAccessTokenParams $(aclVariables)
What I'm missing here?
I've tested your scenario on my side with TFS 2017.3.1, and it works when pass the environment variable as an argument. You can upgrade your TFS first and try again. Attach my steps for your reference:
1.
2.
3.
4.
Non-secret variables are already stored as environment variables; you do not need to do anything special to access them. You can access them with $ENV:VariableName. Periods are replaced with underscores. So Foo.Bar would be $env:FOO_BAR.
Secret variables should be passed in to the script that requires them.
However, this only applies on the agent. If you're using the PowerShell On Target Machines task to run a script, you need to pass the variables as arguments to the script. There is no way around this, unless you choose to use deployment groups.
Or, better yet, follow a configuration-as-code convention and store application-specific values in source controlled configuration files that your scripts read, so that you are not tightly coupled to your deployment orchestration platform.
The case: I have a project where I use nuget packages sharing small libraries between components. I use nuget packages produced by CI builds and once they are done I let the pull request go into master branch and this build will produce a new nuget package which will be used in production.
Nuget package created by CI build has the following properties:
Version number: X.Y.Z-CI-yyyyMMdd-HHmmss
Contains pdb files too
Contains documentation xml file
Nuget package create by Release build has the following properties:
Version number: X.Y.Z
Contains documentation xml file
VSTS build provides the option to use datetime in build name, so it will be unique always. The problem is here.
VSTS build uses localtime (I'm in GMT+2)
NugetCommand task of VSTS uses only UTC and bug ticket about it
As a result I have a strangle looking consistency between my builds and nuget packages:
Nuget package: 1.0.0-CI-20170709-201010
Build: BuildName-BranchName-20170709-181010
Another problem NugetCommand and VSTS cooperation is that, they take the timestamp in different moment, so there is a difference between the two timestamp beside the two hours. It is not that big deal because I don't kick off builds on same build-branch in every second, but still...
NugetCommand has the ability to read the version number of the package it will create from BuildNumber, which is the same as VSTS going to give the new artifact.
So, I would like to solve this problem until they make it more consistent. I already reported to them a few requests. What I figured out so far is using PowerShell to populate a variable with timestamp and it will be used by VSTS build and NugetCommand task.
I followed the example here but it deals with only strings and not date.
I put together the following script, but it does not provide the result I would like to have.
Powershell task 1:
Write-Host "Setting up the date time for build variable and nuget package identifiers"
Write-Host "##vso[task.setvariable variable=dateTimeIdentifier]Get-Date -format yyyyMMdd-Hmmss"
Write-Host "Get-Date -format yyyyMMdd-Hmmss"
Get-Date -format yyyyMMdd-Hmmss
Powershell task 2 where the argument is:
-dateTimeIdentitfier"$(dateTimeIdentifier)"
Write-Host "Checking: $(dateTimeIdentifier)"
And the result is where you can see that the Powershell command is the value of the variable not the formatted datetime.
Setting up the date time for build variable and nuget package identifiers
Get-Date -format yyyyMMdd-Hmmss
20170709-202457
Checking: Get-Date -format yyyyMMdd-Hmmss
I know how to solve issues like this in bash, but I don't have build agent where bash is available.
Bash like solution would like to be like this, which is not correct, but the command between `` will be executed first and the result will be passed through the remaining command as parameter.
Write-Host "##vso[task.setvariable variable=dateTimeIdentifier]`Get-Date -format yyyyMMdd-Hmmss`"
My question is, how to solve this in VSTS build and its task environment? Is there a solution for this? Is my approach correct?
You can change your first PowerShell task (Powershell task 1) as below:
Write-Host "Setting up the date time for build variable and nuget package identifiers"
$date=$(Get-Date -format yyyyMMdd-Hmmss)
Write-Host "##vso[task.setvariable variable=dateTimeIdentifier]$date"
Write-Host "Get-Date -format yyyyMMdd-Hmmss"
Get-Date -format yyyyMMdd-Hmmss
Add a variable in power shell script, and then set a VSTS (Azure DevOps) variable to use in subsequent tasks
If you want to have the datetime show when you write the output using write-host, and I highly recommend you use write-output instead, you can do the following:
$DateTime = Get-Date -format yyyyMMdd-Hmmss
Write-Host "Checking: $DateTime"
This will output this:
Checking: 20170710-64624
EDIT: Now for your issue, sorry I missed it the first time, the dateTimeIdentifier being returned looks like it is a string "Get-Date -format yyyyMMdd-Hmmss"
So if you want to execute that code, you need to first, make a script block, then execute that script block.
$ScriptBlock = [ScriptBlock]::Create("Get-Date -format yyyyMMdd-Hmmss")
& $ScriptBlock