azure-devopsyamlazure-pipelinesazure-pipelines-yaml

Nesting Expressions in Azure DevOps


Here is a parameter I have at the top-most level of my Azure Pipeline architecture:

    components:
      libdummy:
        name: "libdummy"
        url: "github.com/libdummy"
        branch: "${{ parameters.libdummybranch }}"
        recipes:
        - "libdummy"
      libbaloney:
        name: "libbaloney"
        url: "github.com/libbaloney"
        branch: "${{ parameters.libbaloneybranch }}"
        recipes:
        - libbaloney
        - nativesdk_libbaloney

I need to extract arrays or lists, for example, how can I create a new variable which is all the urls ?

I'm trying to combine expressions such as:

URLS: ${{ each component.url in components }}

(not even sure that component.url is even legal) and:

$ {{ join(";",myArray) }}

that would create a long string, I guess it's not absolutely necessary to do that, but I'm throwing this in as another examples of how I'd like to combine expressions. So all in all, I'd like to try doing something like:

URLS_string: ${{ join(";",${{ each component.url in components }}) }}

but Azure DevOps Pipeline always throws me out when I try doing that. What's the correct syntax for nesting expressions and manipulating objects ?


Solution

  • Your yaml represents the components as a single object, where the properties of that object are the components. This limits you as it’s a fixed object with a well known structure which cannot be iterated easily.

    If you were to represent your components as a sequence (starting with -) suddenly your object becomes easier to navigate.

    parameters:
    - name: components
      type: object
      default:
      - name: "libdummy"
        url: "github.com/libdummy"
        branch: x
        recipes:
         - "libdummy"
       - name: "libbaloney"
         url: "github.com/libbaloney"
         branch: y
         recipes:
         - libbaloney
         - nativesdk_libbaloney
    
    

    As an array, you can use filtered array syntax to reference all the elements in the array. For example, to get all the URLs: ${{ parameters.components.*.url }}

    Note that ${{ each … }} can be used to iterate sequences or objects. When used with sequences, each iterates through the array and returns an object that you can access values through their properties (component.url). When each is used on a complex object, it iterates over the properties of the object and returns a mapping (name value pair) that you access via key and value. Regardless the type used, each cannot be used inline as an expression.

    To create a variable with a concatenated list of URLs:

    variables:
      UrlList: ${{ join(“;”, parameters.components.*.url) }}