I need to pass a collection of environment variables to a yml template so that those variables can be used for one of its task.
I developed this sample yml template named my-new-template.yml:
parameters:
- name: envTests
type: object
default: []
steps:
- powershell: |
Write-Host "$env:variable1"
displayName: 'Display environment'
env:
${{ parameters.envTests }}
where practically I pass the collection as an object input parameter named envTests and then this object is passed as it is to the env group of my powershell task.
The solution was taken from this SO thread Set environment variables into azure devops pipelines step from template.
In my main pipeline I call that template this way:
- job: Job1
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: none
- template: my-new-template.yml
parameters:
envTests:
- name: variabile1
value: valuevariabile1
- name: variabile2
value: valueVariabile2
- template: my-new-template.yml
I make two calls just to see that build is not broken if no environment variables are provided. It seems good to me but I got this exception
my-new-template.yml (Line: 12, Col: 5): A sequence was not expected
Could someone please tell me what I'm doing wrong? Thanks a lot
In the main YAML you can change to like as below to fix the issue.
- job: Job1
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: none
- template: my-new-template.yml
parameters:
envTests:
variabile1: valuevariabile1
variabile2: valueVariabile2
EDIT:
If you want conditionally execute the powershell
task based on the length of parameter 'envTests
' in the template YAML, you can add the conditional like as below in the template YAML.
# my-new-template.yml
parameters:
- name: envTests
type: object
default: []
steps:
- ${{ if not(eq(length(parameters.envTests), 0)) }}:
- powershell: |
Write-Host "variable1 = $env:variable1"
Write-Host "variable2 = $env:variable2"
displayName: 'Display environment'
env:
${{ parameters.envTests }}
See below example:
# azure-pipelines.yml
stages:
- stage: A
jobs:
- job: A1
steps:
- checkout: none
- template: my-new-template.yml
parameters:
envTests:
variable1: valuevariabile1
variable2: valueVariabile2
- job: A2
steps:
- checkout: none
- template: my-new-template.yml
A1
, the powershell
task is executed as the values are provided to the parameter 'envTests
'.A2
, the powershell
task is not executed as no values are provided to the parameter 'envTests
'.EDIT_2:
If you want to run the PowerShell task in some jobs when no any environment variables provided, you can update your template YAML referring the sample below.
# my-new-template.yml
parameters:
- name: envTests
type: object
default: []
steps:
- ${{ if not(eq(length(parameters.envTests), 0)) }}:
- powershell: |
Write-Host "PowerShell scripts that need to provide some environment variables."
Write-Host "variable1 = $env:variable1"
Write-Host "variable2 = $env:variable2"
displayName: 'Have env var provided'
env:
${{ parameters.envTests }}
- ${{ if eq(length(parameters.envTests), 0) }}:
- powershell: |
Write-Host "PowerShell scripts that do not need to provide some environment variables."
Write-Host "There are no any environment variables provided."
displayName: 'No env var provided'
- powershell: |
Write-Host "This task will always execute."
Write-Host "Regardless of whether there are environment variables provided."
displayName: 'Always run'
# azure-pipelines.yml
stages:
- stage: A
jobs:
- job: A1
steps:
- checkout: none
- template: my-new-template.yml
parameters:
envTests:
variable1: valuevariabile1
variable2: valueVariabile2
- job: A2
steps:
- checkout: none
- template: my-new-template.yml
EDIT_3:
In above EDIT_2, If you want to combine the first and the second PowerShell tasks to be only one PowerShell task, you can do like as below.
# my-new-template.yml
parameters:
- name: envTests
type: object
default: []
steps:
- powershell: |
Write-Host "variable1 = $env:variable1"
Write-Host "variable2 = $env:variable2"
displayName: 'Show env var'
${{ if not(eq(length(parameters.envTests), 0)) }}:
env:
${{ parameters.envTests }}
. . .