Search code examples
continuous-integrationazure-pipelinesmauicicd

CI/CD Multi-instance mobile app pipeline matrix in combination with variable groups


I created a Multi-instance mobile app pipeline. It creates an apk and an aab per tenant (client). To do so I make use of a pipeline parameter where I can set multiple tenants at a time:

- name: Tenants
  displayName: "Select Tenants to build for"
  type: object
  default:
  - ExampleClient
  - ExampleClient2

Now in the BuildAndroid stage I want to build an .apk and .aab per tenant which I use a matrix for and a compile time for loop:

- stage: BuildAndroid
  variables:
  - group: ${{ TenantName }}
  jobs:
  - job: 'BuildAndroid'
    strategy:
      matrix:
        ${{ each tenant in parameters.Tenants }}:
          ${{ format('{0}_APK', tenant) }}:
            TenantName: ${{ tenant }}
            BuildFormat: 'apk'
            SignAndroid: $(SignAndroidApk)
            BuildApp: $(PackageAndroidApk)
          ${{ format('{0}_AAB', tenant) }}:
            TenantName: ${{ tenant }}
            BuildFormat: 'aab'
            SignAndroid: $(SignAndroidAab)
            BuildApp: $(PackageAndroidAab)
    displayName: 'Build Android'

"- group: ${{ TenantName }}" is responsible for setting the tenant-specific variables and secrets but TenantName is not available because it's part of the matrix for loop. Variable groups can't be set dynamically at runtime using $() syntax. So how can I go about this?

  (Line: 53, Col: 12): Unrecognized value: 'TenantName'. Located at position 1 within 
  expression: TenantName.

What I expect: I can select multiple tenants before the pipeline runs and it builds the apk and aab for all selected tenants based on tenant specific variables and secrets.

How can I change my approach to make this work?


Solution

  • Assuming you would expect to reference variable groups dynamically with the group names of ${{ TenantName }}, whose names are the same values as those defined in parameters.Tenants, the sample below works. As required, you can also define multiple tenants for parameters.Tenants at queue time and pipeline jobs will be expanded for each value in parameters.Tenants and matrix with values retrieved from respective variable group.

    parameters:
    - name: Tenants
      displayName: "Select Tenants to build for"
      type: object
      default:
      - ExampleClient1
      - ExampleClient2
    stages:
    - stage: BuildAndroid
      jobs:
      - ${{ each tenant in parameters.Tenants }}:
        - job: 'BuildAndroid_${{ tenant }}'
          dependsOn: []
          displayName: 'Build Android for ${{ tenant }}'
          variables:
          - group: ${{ tenant }}
          strategy:
            matrix:
              ${{ format('{0}_APK', tenant) }}:
                TenantName: ${{ tenant }}
                BuildFormat: 'apk'
                SignAndroid: $(SignAndroidApk)
                BuildApp: $(PackageAndroidApk)
              ${{ format('{0}_AAB', tenant) }}:
                TenantName: ${{ tenant }}
                BuildFormat: 'aab'
                SignAndroid: $(SignAndroidAab)
                BuildApp: $(PackageAndroidAab)
          steps:
          - script: |
              echo "TenantName: $(TenantName)"
              echo "BuildFormat: $(BuildFormat)"
              echo "SignAndroid: $(SignAndroid)"
              echo "BuildApp: $(BuildApp)"
    
    

    enter image description here