Reputation: 1658
I have the following pipeline variables:
---
variables:
models:
- name: model1
image_name: image1
- name: model2
image_name: image2
However, this is not allowed: A sequence was not expected
. It seems that pipeline variables can only be single line strings. Is there a clever way to work around this? I've read about convertToJson, but it's not desirable/readable to write the models
variable in a single line json string.
For context, I'm passing this variable as a parameter to a template, where I will be looping over parameters.models
and run a stage for each model
, like this:
- ${{each model in parameters.models}}:
- stage: {{ model.name }}
Apparently there is a very old unresolved issue that could provide a solution... What would be the best workaround?
Upvotes: 5
Views: 18578
Reputation: 7146
DevOps YAML pipeline don't support such YAML structure:
variables:
models:
- name: model1
image_name: image1
- name: model2
image_name: image2
The variables in DevOps pipeline concept is only string.
And this place:
- ${{each model in parameters.models}}:
- stage: {{ model.name }}
Here are two usages in DevOps YAML tech, were named conditional insertion and template expression.
Both of them need valid structure in DevOps YAML. Variables in DevOps YAML concept doesn't support such structure, so these usages are not possible.
A possible way is make your YAML pipeline like below:
trigger:
- none
pool:
vmImage: ubuntu-latest
parameters:
- name: models
type: object
default:
- name: model1
image_name: image1
- name: model2
image_name: image2
stages:
- ${{each model in parameters.models}}:
- ${{ each modelcontent in model }}:
- ${{ if eq(modelcontent.Key, 'name') }}:
- stage: '${{ modelcontent.Value }}'
jobs:
- job:
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
Results:
Parameters can pass YAML object, and then use them in compile time usages. that's why I use parameters.
If you want handle the parameters automatically, the only way it to use another script/code/app to parse the YAML content getting from the repository and then change it. And after you finish the change, follow this to push back the changed YAML:
Upvotes: 7
Reputation: 1646
John Folberth almost does what you want, except he isn't passing it as a parameter to the yaml but to underlying templates:
https://blog.johnfolberth.com/advanced-azure-devops-yaml-objects/
The ConvertToJson is the other alternative, André van der Goes explains it in this blog post:
https://www.automagical.eu/posts/passing-complex-variables-devops-yaml/
Upvotes: 1