3

I have two templates (build-tsmain-project.yml and build-single-project.yml) which I call from another template like this:

steps:
  - ${{ each project in parameters.projects }}:
      - ${{ if ne(project.disable, 'true') }}:
          - ${{ if eq(project.name, 'TSMain') }}:
              - template: build-tsmain-project.yml
                parameters:
                  name: ${{ project.name }}
                  shortName: ${{ project.shortName }}
                  path: ${{ project.name }}.sln
                  moreBuildArgs: ${{ parameters.restoreArgs }} ${{ parameters.moreBuildArgs }} ${{ project.moreBuildArgs }}
                  testFilter: ${{ project.testFilter }}
                  ${{ if parameters.withCoverage }}:
                    moreTestArgs: ${{ parameters.coverageArgs }}
                    publishTestResults: false
                  noTest: ${{ project.noTest }}
          - ${{ if ne(project.name, 'TSMain') }}:
              - template: build-single-project.yml
                parameters:
                  name: ${{ project.name }}
                  shortName: ${{ project.shortName }}
                  path: ${{ project.name }}.sln
                  moreBuildArgs: ${{ parameters.restoreArgs }} ${{ parameters.moreBuildArgs }} ${{ project.moreBuildArgs }}
                  testFilter: ${{ project.testFilter }}
                  ${{ if parameters.withCoverage }}:
                    moreTestArgs: ${{ parameters.coverageArgs }}
                    publishTestResults: false
                  noTest: ${{ project.noTest }}

That is a problem, because I duplicate the parameters - not DRY.

The only working solution that is DRY which I could find involves introducing a new template (build-single-project-or-tsmain.yml):

parameters:
  - name: template_name
    type: string
  - name: template_parameters
    type: object

steps:
  - template: ${{ parameters.template_name }}
    parameters: ${{ parameters.template_parameters }}

Which allows me to rewrite the original code like this:

steps:
  - ${{ each project in parameters.projects }}:
      - ${{ if ne(project.disable, 'true') }}:
          - template: build-single-project-or-tsmain.yml
            parameters:
              ${{ if eq(project.name, 'TSMain') }}:
                template_name: build-tsmain-project.yml
              ${{ if ne(project.name, 'TSMain') }}:
                template_name: build-single-project.yml
              template_parameters:
                name: ${{ project.name }}
                shortName: ${{ project.shortName }}
                path: ${{ project.name }}.sln
                moreBuildArgs: ${{ parameters.restoreArgs }} ${{ parameters.moreBuildArgs }} ${{ project.moreBuildArgs }}
                testFilter: ${{ project.testFilter }}
                ${{ if parameters.withCoverage }}:
                  moreTestArgs: ${{ parameters.coverageArgs }}
                  publishTestResults: false
                noTest: ${{ project.noTest }}

Now I am wondering if there is a way to avoid introducing a new template and still have a DRY solution?

We use Azure DevOps Server 2020 (on-prem).

mark
  • 59,016
  • 79
  • 296
  • 580

0 Answers0