Provide a pipeline queue time variable with default value - azure-devops

In Azure Pipelines you can set pipeline variables at queue time. You can use such a variable the same way as variables defined by the pipeline itself.
Example:
# pipeline.yml
steps:
- checkout: none
- template: steps/some.yml
parameters:
name: $(queueTimeVar)
# steps/some.yml
parameters:
name: 'World'
steps:
- bash: |
echo "Hello ${{ parameters.name }}!"
But if the variable isn't set explicitly, the pipeline evaluates this expresstion to the string itself. The step template would be called with name: '$(queueTimeVar)' and print Hello $(queueTimeVar)!.
How could I set a default value if the variable wasn't set?
I tried adding the default value as variable but it didn't work as expected.
variables:
queueTimeVar: MyDefault
Afterwards the queue time variable had no effect. The variable was always the YAML value.
As workaround I had to add the default handling to every task which uses the value.
# bash task
value="MyDefault"
if [ -n "$QUEUETIMEVAR" ]; then
value="$QUEUETIMEVAR"
fi

How could I set a default value if the variable wasn't set?
If what you mean is does not set this variable queueTimeVar in anywhere, including in Variables tab in trigger page, or Variables tab on YAML configuration page. Unfortunately to say, No, without the variable set explicitly, the server could not know where should get the value.
Until now, if the pipeline configure type you are using is YAML, The server can only recognize the variables which defined in three places: (1) Variable block in YAML script, (2) Variables panel in the configuration page, (3) Variables tab in the Triggers setting.
Any variables which does not defined in one of these three locations are not recognized by the server, even just create one new variable in the below location:
In one word, if you just create a new variable in queue time and have not define it in that three location firstly, the server still could not recognize the variable and its value.
So, you must set variables in one of locations I mentioned previously. Or the pipeline would not get it.

Related

How can I define env variable value during the release phase in Azure?

I have an Nx monorepo project set up. I want to set some environment variables to use throughout my app. I'm looking for a solution where I can define a value for these variables during the release process to each environment (QA, Test, Dev).
Example:
NX_API_URL is my environment variable in my .env file.
If I release to QA env the variable should be NX_API_URL=api-url-qa.com.
If I release to Test env the variable should be NX_API_URL=api-url-test.com
I have found solutions during the build process but that's not going to work, it needs to be at the release phase. How can I accomplish this?
If the file that you'd like to modify during the deployment process is either XML or JSON you can define the URLs as tokens and use standard 'FileTransform' task to replace them: https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/file-transform-v2?view=azure-pipelines
For more details regarding file transformation please refer to documentation: https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/transforms-variable-substitution?view=azure-devops&tabs=Classic
If none of the links above will help you with this, then I'd suggest to create PS script to do whatever modifications are required, like adding a line after specific line definition: https://social.technet.microsoft.com/Forums/office/en-US/fabc9790-0ffe-43b2-9d6b-bc483cd28bb6/add-line-to-a-text-file-just-after-a-specific-line-with-powershell?forum=winserverpowershell

How to set environment variables in kubernetes deployment.yaml file as a file read

I am trying to set environment variables to kubernetes deployment in following way.
env:
- name: username
value: $(cat /vault/secrets/config.txt | awk ' NR == 2')
For the environment variable value, I am trying to read the first line of a file. But, in application initialization, the environment variable is set as just the text value denoted above without evaluating the cat expression. How to set the environment variable in this scenario properly?. Thank you.
Best way to achieve your goal is described in Vault documentation: https://www.vaultproject.io/docs/platform/k8s/injector/examples#environment-variable-example

Incorrect Identification of Target Branch - SystemPullRequestTargetBranch. What is the workaround?

~
System variable System.PullRequest.TargetBranch cannot be used in templates. What is the workaround for below.
It kind of depends where you want to use Environment variable. If in deployment job to set environment, you can't as it has to be known at compilation time.
If you want to use in place which can be established at runtime, you can use logging command to setup variable.
- pwsh: |
if ( 'refs/heads/release-uat' -in #('$(Build.SourceBranch)','$(System.PullRequest.TargetBranch)') )
{
Write-Host "##vso[task.setvariable variable=Environment;]uat"
}
However, variable set in that way can't be use in some places.

How to pass powershell script variable values to downstream task in Release pipeline

Created a CD with few steps starting from "Azure PowerShell Task".
In Azure PowerShell tasks, executing a PowerShell script file and set a value in a variable.
At the end of the script I have set the variable with a value –
echo "##vso[task.setvariable variable=myvariable;isSecret=false;isOutput=true;]myvalue"
myvariable is the variable
myvalue is the value.
Based on the value of “myvariable”; downstream task will be executed or skipped. Mentioned "Custom Condition" in downstream task (Task - Azure Create or Update Resource) –
and(succeeded(), eq(variables[‘myvariable’], ‘myvalue’))
But, it’s always skipping the step; despite the correct value is passing. Here is my release tasks snippet -
How do I overcome?
try
Write-Host "##vso[task.setvariable variable=myvariable;isSecret=false;isOutput=true;]myvalue"
And then
and(succeeded(), eq(variables['myvariable'], 'myvalue'))
In the second part, the code you pasted in has the incorrect quote types, you had curly quotes ‘ ’ rather than the normal straight quotes ' '
You often end up with the wrong quotes if copying / pasting from Word or Outlook. I'm sure there's a proper a typography term for them.
Thanks everyone for your valuable input. Resolution -
PowerShell Script -
$myvalue="hello"
Write-Host "##vso[task.setvariable variable=myvariable]$myvalue"
Assign value ("hello") in a variable ($myvalue), then set it in "Write-Host". Direct value did not work for me.
Now we can use/verify "myvariable" value in downstream tasks in Custom Condition as mentioned by #Alex KeySmith.
and(succeeded(), eq(variables['myvariable'], 'hello'))
task -
Works in Build and Release pipeline.

VSO(TFS) - get current date time as variable

How can I get a current date-time and pass it as a variable to some Deployment task?
You can define a variable with any value, and then modify the variable as current date. Detail steps as below:
Define a variable in release
Assume the variable name is time, and we set the value as none. If you need to use the variable for a environment, you can define it in environment variables. Else you should define it in variables Tab.
Add a power shell task at the begin of deploy tasks:
Type: Inline Script.
Inline script:
$date=$(Get-Date -Format g);
Write-Host "##vso[task.setvariable variable=time]$date"
Note:
I use the date format as MM/DD/YYYY HH:MM AM/PM here. You can use other date formats.
For the subsequent deploy task, if you want to use current date time, you can direct use $(time).
Update
Documentation for Defining Variables: Set Variables Using Expressions has a nugget of gold for the answer to this question in the example for creating a counter value that is reset daily.
a: $[counter(format('{0:yyyyMMdd}', pipeline.startTime), 100)]
The pipeline.startTime variable used here is subtle and not mentioned anywhere in the Pipeline Predefined Variables documentation, even when being careful to land on the correct documentation based on the pipeline method being used. As is suggested HERE and in some of the answers on this thread, certain variables may have different values or not exist at all depending on where you are while trying to access them.
There is now a variable specific to a release stage named "Release.Deployment.StartTime" or if you use it in powershell the environment variable is "Release_Deployment_StartTime".
It's in UTC and the format is "yyyy-MM-dd HH:mm:ssZ"
ex: "2018-11-09 21:23:27Z"
NOTE: This variable is set at the time the deployment stage is started, so if you have pre-deployment approvals the time will be set before any approvals are completed. From my testing if you have multiple stages that execute at the same time it will be the same between them, even if one stage waits for the other due to limited agent availability.
I'm using Azure DevOps online, unsure if local TFS installations will have this.
For those who use Linux on tfs:
Define variable
Make sure it has "Settable at queue time set"
Create a script in root of your repository
set-build.date.sh:
#!/usr/bin/env bash
DATE=$(date '+%d/%m/%Y %H:%M:%S')
echo "##vso[task.setvariable variable=BUILD_DATE;]$DATE"
Other options are listed here.
Add shell script right after get sources
Type bash to find this task.
Done, you can use BUILD_DATE variable in later tasks :)
An easier way is
$(Date:MMddyy)
Some options are only available in the Build Definition options section. The date formatting is one of them. However, if you were to go into the options section, set the build number format as $(Date:yyyyMMdd-HHmmss), you could then use the $(Build.BuildNumber) variable in your tasks.
More info here - https://learn.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/variables?tabs=batch
Based on answer of Marina Liu (here) for quick copy and paste.
Define variable on top:
variables:
buildTimeStamp: # will be set by script
# ...
Add this as first task (and change format as needed):
- task: PowerShell#2
displayName: set variable buildTimeStamp
inputs:
targetType: 'inline'
script: |
$date=$(Get-Date -Format yyyy-MM-dd_HH.mm);
Write-Host "##vso[task.setvariable variable=buildTimeStamp]$date"
Now you can use variable $(buildTimeStamp) in your code below.