Search code examples
azureazure-devopsyamlazure-pipelines

Azure DevOps Pipeline Expression Evaluation


I have an Azure DevOps pipeline that builds and deploys a Visual Studio Tools for Office (VSTO) addin for Viso. Depending upon the branch I want the InstallUrl to be customized as part of the MSBuild publish task. To that end I have written a YAML expression that tailors that conditionally sets msbuildArguments per YAML fragment below.

When the pipeline runs I can see that the expression does not execute as expected becuase msbuildArgumentProduction is always being selected. Having reviewed MS doco I cannot understand what is wrong.

stages:
- stage: build
  variables:
    isProduction: $[eq(variables['Build.SourceBranch'], 'refs/heads/production')]
    isDevelopment: $[eq(variables['Build.SourceBranch'], 'refs/heads/development')]
    solution: '**/ModelGenVisioAddIn.sln'
    buildPlatform: 'Any CPU'
    buildConfiguration: 'Release'
    msbuildArgumentDevelopment: '-v:d /t:publish  /property:InstallUrl=https://exampleDev1.com/ /property:ApplicationVersion=1.0.0.136 /p:PublishDir=MG4V\'
    msbuildArgumentProduction: '-v:d /t:publish  /property:InstallUrl=https://exampleProd1.com/ /property:ApplicationVersion=1.0.0.136 /p:PublishDir=MG4V\'

  jobs: 
    - job: build_job
      pool:
        vmImage: 'windows-latest'
      steps: 
         - task: MSBuild@1
           displayName: 'Publishing ModelGen for Visio (MG4V)'
           inputs:
            solution: '$(solution)'
            configuration: '$(buildConfiguration)'
            ${{ if eq(variables.isDevelopment, true) }}:
              msbuildArguments: '$(msbuildArgumentDevelopment)'
            ${{ else }}:
              msbuildArguments: '$(msbuildArgumentProduction)'

Any advice / help would be gratefully received


Solution

  • The expression '${{ xxxx }}' is processed at compile-time before runtime, and the expression '$[xxxx]' is processed at runtime after compile-time. See "Understand variable syntax".

    enter image description here

    So, when the expression '${{ if eq(variables.isDevelopment, true) }}' of condition is processed at compile-time, the value of 'isDevelopment' variable has not been extended.

    For your case, you can change the expression of condition like as below:

    stages:
    - stage: build
      variables:
        isProduction: $[eq(variables['Build.SourceBranch'], 'refs/heads/production')]
        isDevelopment: $[eq(variables['Build.SourceBranch'], 'refs/heads/development')]
        solution: '**/ModelGenVisioAddIn.sln'
        buildPlatform: 'Any CPU'
        buildConfiguration: 'Release'
        msbuildArgumentDevelopment: '-v:d /t:publish  /property:InstallUrl=https://exampleDev1.com/ /property:ApplicationVersion=1.0.0.136 /p:PublishDir=MG4V\'
        msbuildArgumentProduction: '-v:d /t:publish  /property:InstallUrl=https://exampleProd1.com/ /property:ApplicationVersion=1.0.0.136 /p:PublishDir=MG4V\'
    
      jobs: 
        - job: build_job
          pool:
            vmImage: 'windows-latest'
          steps: 
             - task: MSBuild@1
               displayName: 'Publishing ModelGen for Visio (MG4V)'
               inputs:
                solution: '$(solution)'
                configuration: '$(buildConfiguration)'
                ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/development') }}:
                  msbuildArguments: '$(msbuildArgumentDevelopment)'
                ${{ else }}:
                  msbuildArguments: '$(msbuildArgumentProduction)'