Martin
Martin

Reputation: 45

Passing a dictionary to a template in azure devops yaml

I want to run a loop in a template to download two artifacts with specific versions.

I have been trying to formulate solutions for this but no luck yet, this is what I've came up until now but i think its not supported.

Can someone point me in the right direction if this is possible?

pipeline.yml

variables:
- template: project.variables.yml

jobs:
- job: 'Deploy'
  steps:
  - template: instantclient.template.yml
    parameters:
      artifacts:
        oracle-instantclient:
          package: 'oracle-instantclient'
          packageVersion: ${{ variables.oracle-instantclient }}
        oracle-data-access-components:
          package: 'oracle-data-access-components'
          packageVersion: ${{ variables.oracle-data-access-components }}

instantclient.template.yml

parameters:
- name: artifacts
  type: object
- name: feed
  default: ahitapplicationteam
- name: downloadDirectory
  default: deployment/s

steps:
  - ${{ each artifact in parameters.artifacts}}:
    - template: artifacts.template.yml
      parameters:
        packageVersion: ${{ packageVersion }}
        feed:  ${{ parameters.feed }}
        package: ${{ package }}
        downloadDirectory: ${{ parameters.downloadDirectory }}

artifacts.template.yml

parameters:
- name: packageVersion
- name: feed
- name: package
- name: downloadDirectory

steps:
- task: UniversalPackages@0
  displayName: 'Downloading | Feed: ${{ parameters.feed }} | Package: ${{ parameters.package }}' #| PackageVersion: ${{ parameters.packageVersion }}
  inputs:
    command: 'download'
    downloadDirectory: ${{ parameters.downloadDirectory }}
    vstsFeed:  ${{ parameters.feed }}
    vstsFeedPackage: ${{ parameters.package }}
    vstsPackageVersion: ${{ parameters.packageVersion }}
    verbosity: 'Debug'

Upvotes: 3

Views: 2341

Answers (1)

bryanbcook
bryanbcook

Reputation: 18383

You're on the right track. You need to add the - character to each item in your object to convert it into an array. The object can be an array of simple strings or complex objects. As an object, you can access the properties of your objects in the each loop.

The use of ${{ variables.oracle-data-access-components }} assumes that the oracle-data-access-components variable is available at compile-time when the pipeline is initially processed.

Whether you want to break it into 3 templates is a stylistic decision. I went with 2 templates to simplify readability, but a third template will provide you will some validation for required parameters.

pipeline.yml

variables:
- template: project.variables.yml

jobs:
- job: 'Deploy'
  steps:
  - template: instantclient.template.yml
    parameters:
      artifacts:
        - name: 'oracle-instantclient'
          version: ${{ variables.oracle-instantclient }}
        - name: 'oracle-data-access-components'
          version: ${{ variables.oracle-data-access-components }}

instantclient.template.yml

parameters:
# list of package to download (name, version)
- name: artifacts
  type: object

# azure artifact feed name
- name: feed
  type: string
  default: 'ahitapplicationteam'

# download path for artifacts
- name: downloadDirectory
  type: string
  default: 'deployment/s'

steps:
# loop through the artifacts (name, version)
- ${{ each artifact in parameters.artifacts}}:
 
  # download the artifact
  - task: UniversalPackages@0
    displayName: 'Downloading | Feed: ${{ parameters.feed }} | Package: ${{ artifact.name }}' #| PackageVersion: ${{ artifact.version }}
    inputs:
      command: 'download'
      downloadDirectory: ${{ parameters.downloadDirectory }}
      vstsFeed:  ${{ parameters.feed }}
      vstsFeedPackage: ${{ artifact.name }}
      vstsPackageVersion: ${{ artifact.version }}
      verbosity: 'Debug'

Upvotes: 2

Related Questions