Is it possible to make single VSBuild/VSTest pipeline tasks for multiple build platforms?

47 Views Asked by At

Edit (TL;DR-Answer): No, it is not possible to make a single task for either VSBuild or VSTest that encompasses more than one build platform (or build configuration, for that matter). It is possible to configure both of them only once per YAML as described in the accepted answer by @bright-ran-msft below; however, it is still necessary to produce a separate task for each platform.


I am currently trying to create an Azure DevOps CI pipeline that builds different .NET and C++ projects for different build platforms (x64, x86, Any CPU) and tests them using MSTest and the CppUnitTestFramework.

The YAML-Pipeline currently contains the following tasks for building and testing the projects:

- task: VSBuild@1
  displayName: Build x86 - Release
  inputs:
    solution: 'Solution.sln'
    platform: 'x86'
    configuration: 'Release'
    maximumCpuCount: true
    msbuildArchitecture: 'x64'
    logFileVerbosity: minimal

- task: VSTest@2
  displayName: Test Any CPU - Release
  inputs:
    testAssemblyVer2: |
      **\*Test.dll
    searchFolder: '$(Build.SourcesDirectory)\Bin\AnyCPU\Release'
    runInParallel: true
    runTestsInIsolation: true

- task: VSTest@2
  displayName: Test x86 - Release
    inputs:
      testAssemblyVer2: |
        **\*Test.dll
      searchFolder: '$(Build.SourcesDirectory)\Bin\Win32\Release'
      runInParallel: true
      runTestsInIsolation: true

- task: VSBuild@1
  displayName: Build x64 - Release
  inputs:
    solution: 'Solution.sln'
    platform: 'x64'
    configuration: 'Release'
    maximumCpuCount: true
    msbuildArchitecture: 'x64'
    logFileVerbosity: minimal

- task: VSTest@2
  displayName: Test x64 - Release
  inputs:
    testAssemblyVer2: |
      **\*Test.dll
    searchFolder: '$(Build.SourcesDirectory)\Bin\x64\Release'
    runInParallel: true
    runTestsInIsolation: true

I am trying to minimize the amount of tasks. In my mind, it should be possible to achieve the same outcome as in the YAML above in a simpler manner. I would expect something like the following (note that I changed the path in the searchFolder in order to fetch all subdirectories of the build platforms):

- task: VSBuild@1
  displayName: Build - Release
  inputs:
    solution: 'Solution.sln'
    configuration: 'Release'
    maximumCpuCount: true
    msbuildArchitecture: 'x64'
    logFileVerbosity: minimal

- task: VSTest@2
  displayName: Test - Release
  inputs:
    testAssemblyVer2: |
      **\*Test.dll
    searchFolder: '$(Build.SourcesDirectory)\Bin'
    runInParallel: true
    runTestsInIsolation: true

I have tried to keep both of the build tasks and merge all three test tasks into one. Some of the tests succeeded while the majority failed. This is significant since executing those tests in separated tasks made all of them succeed.

In conclusion:

  • Is it possible to write a build task that encapsulates all build platforms (x64, x86, Any CPU)?
  • Is it possible to write a test task that tests all DLL-Files regardless of their build platform?
  • If one or both of them are not realizable, why would that be the case and does that mean that the original YAML from above is actually the most concise method of formulating these?
1

There are 1 best solutions below

2
Bright Ran-MSFT On BEST ANSWER

You can try like as below:

. . .

parameters:
- name: buildPlatforms
  type: object
  default:
  - 'Any CPU'
  - 'x64'
  - 'x86'

variables:
  buildConfiguration: 'Release'
  TestProjectName: {Your Test Project Name}

jobs:
- job: build
  displayName: 'Build'
  steps:
  . . .
  
  - ${{ each buildPlatform in parameters.buildPlatforms }}:
    - task: VSBuild@1
      displayName: 'Build ${{ buildPlatform }} - $(buildConfiguration)'
      inputs:
        solution: 'Solution.sln'
        ${{ if eq(buildPlatform, 'Any CPU') }}:
          msbuildArgs: '-p:OutputPath=bin\AnyCPU\$(buildConfiguration)'
        ${{ else }}:
          msbuildArgs: '-p:OutputPath=bin\${{ buildPlatform }}\$(buildConfiguration)'
        platform: ${{ buildPlatform }}
        configuration: $(buildConfiguration)
        maximumCpuCount: true
        logFileVerbosity: minimal
    
    - task: VSTest@3
      displayName: 'Test ${{ buildPlatform }} - $(buildConfiguration)'
      inputs:
        testAssemblyVer2: |
          **\*test*.dll
          !**\*TestAdapter.dll
          !**\obj\**
        ${{ if eq(buildPlatform, 'Any CPU') }}:
          searchFolder: '$(System.DefaultWorkingDirectory)\$(TestProjectName)\bin\AnyCPU\$(buildConfiguration)'
          testRunTitle: 'Test-AnyCPU-$(buildConfiguration)'
        ${{ else }}:
          searchFolder: '$(System.DefaultWorkingDirectory)\$(TestProjectName)\bin\${{ buildPlatform }}\$(buildConfiguration)'
          testRunTitle: 'Test-${{ buildPlatform }}-$(buildConfiguration)'
        runInParallel: true
        runTestsInIsolation: true

By this, the pipeline will generate a build step and a test step for each platform (Any CPU, x64 and x86) within the same job.

enter image description here

Related documentations: