Azure DevOps YAML If 条件

Azure DevOps YAML If condition

我正在尝试使用 if 条件来执行一个操作块,但它似乎对我不起作用。我不完全确定我是否正确理解了 if 条件,但这就是我一直在使用它的方式 - 或者至少是它的简化版本。

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

name: MyTest-$(date:yyyyMMdd)$(rev:.r)

trigger: none

resources:
  - repo: self
    clean: false
    fetchDepth: 2

variables:
  - group: TestVG
  - name: EnableSigning
    value: true
  - name: SignDebugBuilds
    value: false

stages:
  - stage: Stage_Build
    displayName: Build Stage
    dependsOn: []

    jobs:
      - job: Job_Build
        displayName: Build Job
        condition: succeeded()
        dependsOn: []
        pool:
          vmImage: 'windows-latest'
        variables:
          BuildPlatform: AnyCPU
        strategy:
          matrix:
            Debug:
              BuildConfiguration: Debug
            Retail:
              BuildConfiguration: Retail
        steps:
          - template: param-test.yml
            parameters:
              Value: 'Build Solution 1'
          #- script: echo 'Build Solution 1'
          - ${{ if and(eq(variables['EnableSigning'], True), or(ne(variables['BuildConfiguration'], 'Debug'), eq(variables['SignDebugBuilds'], True))) }}:
            #- script: echo 'Build Solution 2 IF check'
            - template: param-test.yml
              parameters:
                Value: 'Build Solution 2 IF check'
          - script: echo 'Build Solution 2 COND check'
            condition: and(eq(variables['EnableSigning'], True), or(ne(variables['BuildConfiguration'], 'Debug'), eq(variables['SignDebugBuilds'], True)))

param-test.yml 文件是一个简单的文件,用于回显用于 logging/debugging 目的的行。

parameters:
  Value: string

steps:
  - script: echo '${{ parameters.Value }}'

我的期望是,对于调试版本,我会看到第一个日志,其他 2 个日志将被跳过,而零售版本将打印所有 3 个日志。

但是,我看到的是对于调试版本,打印了第一条和第二条日志,而只跳过了第三条日志(脚本步骤中具有明确条件的日志),而所有 3 个日志都是为零售构建打印的。

为了澄清一些问题,我使用第 3 条日志作为对照来检查条件是否正确。这是我在我们的回购协议中拥有的实际管道的高度简化版本。我们有一个主要的管道 YAML 文件,其中声明了所有变量,包括 EnableSigning 和 SignDebugBuilds。这会调用将 EnableSigning 和 SignDebugBuilds 标志传递给相同的模板文件。这种情况在子模板中发生了几次,直到其中一个子模板(负责构建的子模板)使用 if 检查中的参数。在实际的管道中,我有条件使用参数而不是变量,但结果还是一样。

我已经查看了一些文档,但对于我们可以从 if 语句中得到什么还不是很清楚。而且由于模板标签不支持我们可以传入的明确条件,这似乎是除了维护与标志对应的模板文件的 2 个单独版本之外的唯一选择

在你现在的情况下,'if'关键字无法得到variables['BuildConfiguration'],因为这个变量是在作业运行时创建的。 'if'关键字需要使用运行时参数。

所以,每次job是运行,'if'关键字下的variables['BuildConfiguration']的结果都是NULL。因为在job init的时候,这个变量还没有创建。此变量将在作业 运行 时创建,然后管道将帮助您在作业下创建其他两个作业。

目前的解决方法是将矩阵拆分为不同的两个作业,并使用参数而不是变量。 这是我创建的演示:

name: MyTest-$(date:yyyyMMdd)$(rev:.r)

trigger: none

resources:
  - repo: self
    clean: false
    fetchDepth: 2

parameters:
  - name: EnableSigning
    type: boolean
    displayName: 'EnableSigning'
    default: true
  - name: SignDebugBuilds
    type: boolean
    displayName: 'SignDebugBuilds'
    default: false


variables:
  # - group: TestVG
  # - name: EnableSigning
  #   value: true
  # - name: SignDebugBuilds
  #   value: false
  - name: system.debug
    value: true

stages:
  - stage: Stage_Build
    displayName: Build Stage
    dependsOn: []

    jobs:
      - job: Build_Job_Debug
        pool:
          # vmImage: 'windows-latest'
          name: default
        variables:
          BuildPlatform: AnyCPU
          BuildConfiguration: Debug           
        steps:
          - template: param-test.yml
            parameters:
              Value: 'Build Solution 1'
          
          - ${{ if and(eq(parameters.EnableSigning, true), eq(parameters.SignDebugBuilds, true))}}:
            - template: param-test.yml
              parameters:
                Value: 'Build Solution 2 IF check'
          
          - script: echo 'Build Solution 2 COND check and BuildConfiguration is $(BuildConfiguration)'
            name: 'CMD3_check' 
            condition: eq('${{ parameters.EnableSigning }}', true)
      - job: Build_Job_Retail
        pool:
          # vmImage: 'windows-latest'
          name: default
        variables:
          BuildPlatform: AnyCPU
          BuildConfiguration: Retail             
        steps:
          - template: param-test.yml
            parameters:
              Value: 'Build Solution 1'
          
          - ${{ if or(eq(parameters.EnableSigning, true), eq(parameters.SignDebugBuilds, false))}}:
            - template: param-test.yml
              parameters:
                Value: 'Build Solution 2 IF check'
          
          - script: echo 'Build Solution 2 COND check and BuildConfiguration is $(BuildConfiguration)'
            name: 'CMD3_check'
            condition: eq('${{ parameters.EnableSigning }}', true)

另外,如果需要使用变量BuildConfiguration,也可以在不同的作业下定义。