Azure DevOps Yaml 管道:阶段条件变量语法

Dev*_*psy 3 azure-devops azure-pipelines-yaml multistage-pipeline

我正在开发 azure devops 多阶段 yaml 管道。我在第一阶段设置了一个变量,然后对于下一阶段,我有一个基于该变量的条件。我还在下一阶段检索变量值。显然,在条件级别和阶段级别访问阶段间变量的语法之间存在细微差别。我无法弄清楚我需要在条件中使用的语法。我已经尝试了所有可能的变化,但似乎没有一个有效。在下面的示例中,我期望 lint 阶段能够运行,但它会被跳过。这里的条件的确切语法应该是什么?

stages:
- stage: build
  displayName: build
  pool:
    name: Azure Pipelines
    vmImage: ubuntu-latest
  dependsOn: []
  jobs:
  - deployment: build_job
    environment:
      name: "test"
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            displayName: "get commitMessage variable"
            name: getCommitMessage
            inputs:
              targetType: inline
              pwsh: true
              script: |
                $commitMessage = "abcd_import/"
                echo "setting commitMessage: $commitMessage"
                echo "##vso[task.setvariable variable=commitMessage;isOutput=true]$commitMessage"

- stage: lint
  displayName: lint
  dependsOn:
  - 'build'
  condition: contains(stageDependencies.build.build_job.outputs['build_job.getCommitMessage.commitMessage'], 'import/')
  pool:
    name: Azure Pipelines
    vmImage: ubuntu-latest
  variables:
  - name: BUILD_STAGE_GET_COMMIT_MESSAGE
    value: $[stageDependencies.build.build_job.outputs['build_job.getCommitMessage.commitMessage']]
  jobs:
  - deployment: validate
    environment:
      name: "test"
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PowerShell@2
            displayName: "commitMessage is empty"
            name: fail
            inputs:
              targetType: inline
              pwsh: true
              script: "echo $(BUILD_STAGE_GET_COMMIT_MESSAGE)"
Run Code Online (Sandbox Code Playgroud)

更新(答案):我对此提出了 MS 支持案例并得到了解决方案。正确的语法是

condition: contains(dependencies.build.outputs['build_job.build_job.getCommitMessage.commitMessage'], 'import/')
Run Code Online (Sandbox Code Playgroud)

对于这个奇怪的问题,有几点需要说明:

  • 使用阶段变量的语法与在条件中使用它和使用它作为另一个变量传入的语法不同。
  • 同样,如果源阶段是作业,则语法是不同的。如果源阶段是部署作业,则语法是不同的。
  • 最重要的是,我在 MS 文档中找不到正确的语法。
  • 例如,我找不到任何方法来诊断问题:在构建日志中查看阶段输出 json 确实很有帮助。
  • 最后,我相信 Azure DevOps 团队确实把这个功能搞砸了。作业/部署作业、条件和变量分配的语法应保持一致。以现在的状态来说,实在是太痛苦了。

Bri*_*SFT 5

在一个阶段上,要引用另一个阶段的输出变量,您应该使用以下表达式格式:

  • 在阶段级别,引用另一个阶段的输出变量的格式是dependencies.STAGE.outputs['JOB.TASK.VARIABLE'].
  • 在作业级别,引用另一个阶段的输出变量的格式是stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE'].

更多详细信息,您可以查看有关“在不同阶段使用输出”的文档。

此外,在一个阶段上,如果您使用另一个阶段的输出设置阶段级变量,则应使用 格式stageDependencies.STAGE.JOB.outputs['TASK.VARIABLE']而不是dependencies.STAGE.outputs['JOB.TASK.VARIABLE']. 请参阅此文档

在此输入图像描述

下面是一个例子作为参考:

  1. azure-pipelines.yml
parameters:
- name: RunStgB
  type: string
  default: YesRun
  values:
  - YesRun
  - NoRun

stages:
- stage: A
  displayName: 'Stage A'
  pool:
    vmImage: ubuntu-latest
  jobs:
  - job: A1
    displayName: 'Job A1'
    steps:
    - task: Bash@3
      name: setOutput
      displayName: 'Set output variable'
      inputs:
        targetType: inline
        script: |
          echo "parameters.RunStgB = ${{ parameters.RunStgB }}"
          echo "##vso[task.setvariable variable=RunStgB;isoutput=true]${{ parameters.RunStgB }}"

- stage: B
  displayName: 'Stage B'
  dependsOn: A
  condition: eq(dependencies.A.outputs['A1.setOutput.RunStgB'], 'YesRun')
  variables:
  - name: Output_RunStgB
    value: $[ stageDependencies.A.A1.outputs['setOutput.RunStgB'] ]
  pool:
    vmImage: ubuntu-latest
  jobs:
  - job: B1
    displayName: 'Job B1'
    steps:
    - task: Bash@3
      displayName: 'show output variable'
      inputs:
        targetType: inline
        script: echo "Output_RunStgB = $(Output_RunStgB)"
Run Code Online (Sandbox Code Playgroud)
  1. 结果。

    在此输入图像描述

    在此输入图像描述