Azure DevOps 有条件地执行依赖于另一个阶段中的作业的作业

Azure DevOps Conditional execution of Job that depends on a Job in another Stage

我有一个 pipeline.yaml 看起来像这样

pool:
  vmImage: image

stages:
  -stage: A
   jobs: 
     -job: a
      steps: 
     - script: |
          echo "This is stage build"
          echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes"
        name: BuildStageRun
  -stage: B
   jobs:
      -job: b
       steps: #do something in steps

      -job: c
       dependsOn: a
       condition: eq(dependencies.build.outputs['BuildStageRun.doThing'], 'Yes')
       steps:
        - script: echo "I am scripting" 

所以,有 2 个阶段,A 有一份工作 aB有 2 个工作 bc。我想让作业 c 仅在作业 a 执行后才执行。我试图通过将作业 a 中的变量 doThing 设置为 Yes 来实现,然后在作业 c[= 中检查此变量34=]。

但是我得到一个错误:

Stage plan job c depends on unknown job a.

变量定义和条件定义取自Azure documentation

你对如何让它工作有什么建议吗?

因为你不能依赖另一个阶段的工作,你可以将阶段B依赖于阶段A或将工作c依赖于工作b。

你无法通过 YAML 条件实现你的目标,因为你想使用你在第一阶段声明的变量,第二阶段不知道这个变量,Azure DevOps don't support it yet:

You cannot currently specify that a stage run based on the value of an output variable set in a previous stage.

您可以将阶段 B 依赖于 A,因此如果在阶段 A 中只有一项工作,您将阶段 B 依赖于阶段 A:

- stage: B
  dependsOn: A

虽然 Shayki 是正确的,它不受支持 - 但我目前正在使用一种解决方法。我在这个博客的帮助下使用的 https://medium.com/microsoftazure/how-to-pass-variables-in-azure-pipelines-yaml-tasks-5c81c5d31763

基本上您可以正常创建输出,然后将变量发布为管道工件。在下一阶段,您将阅读第一份工作中的工件,并使用它来构建您的条件,例如

stages:

  - stage: firststage
    jobs:

      - job: setup_variables
        pool:
          vmImage: 'Ubuntu-16.04'
        steps:

          - powershell: |
              $ShouldBuildThing1 = $true
              # Write to normal output for other jobs in this stage
              Write-Output "##vso[task.setvariable variable=BuildThing1;isOutput=true]$ShouldBuildThing1"
              # Write to file to publish later
              mkdir -p $(PipelineWorkspace)/variables
              Write-Output "$ShouldBuildThing1" > $PipelineWorkspace/variables/BuildThing1
            name: variablesStep

          # Publish the folder as pipeline artifact
          - publish: $(Pipeline.Workspace)/variables
            artifact: VariablesArtifact

       - job: build_something
         pool:
          vmImage: 'Ubuntu-16.04'
         dependsOn: setup_variables
         condition: eq(dependencies.setup_variables.outputs['variablesStep.BuildThing1'], 'true')
         variables:
           BuildThing1: $[dependencies.setup_variables.outputs['variablesStep.BuildThing1']]
         steps:
           - powershell: |
               Write-Host "Look at me I can Read $env:BuildThing1"

           - somethingElse:
               someInputArgs: $(BuildThing1)


  - stage: secondstage
    jobs:

      - job: read_variables
        pool:
          vmImage: 'Ubuntu-16.04'
        steps:
          # If you download all artifacts then foldername will be same as artifact name under $(Pipeline.Workspace). Artifacts are also auto downloaded on deployment jobs.
          - task: DownloadPipelineArtifact@2
            inputs:
              artifact: "VariablesArtifact"
              path: $(Pipeline.Workspace)/VariablesArtifact

          - powershell: |
              $ShouldBuildThing1 = $(Get-Content $(Pipeline.Workspace)/VariablesArtifact/BuildThing1)
              Write-Output "##vso[task.setvariable variable=BuildThing1;isOutput=true]$ShouldBuildThing1"
            name: variablesStep

      - job: secondjob
        pool:
          vmImage: 'Ubuntu-16.04'
        dependsOn: read_variables
        condition: eq(dependencies.read_variables.outputs['variablesStep.BuildThing1'], 'true')
        variables:
           BuildThing1: $[dependencies.setup_variables.outputs['variablesStep.BuildThing1']]
         steps:
           - powershell: |
               Write-Host "Look at me I can Read $env:BuildThing1"

           - somethingElse:
               someInputArgs: $(BuildThing1)

看起来 Microsoft 现在提供了一些选项。

首先是job-to-job dependencies across stages

来自微软:

In this example, job B1 will run whether job A1 is successful or skipped. Job B2 will check the value of the output variable from job A1 to determine whether it should run.

trigger: none

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  dependsOn: A
  jobs:
  - job: B1
    condition: in(stageDependencies.A.A1.result, 'Succeeded', 'SucceededWithIssues', 'Skipped')
    steps:
    - script: echo hello from Job B1
  - job: B2
    condition: eq(stageDependencies.A.A1.outputs['printvar.shouldrun'], 'true')
    steps:
     - script: echo hello from Job B2

此外,还有另一个选项,您可以 consume output variables across stages

来自微软网站:

Stages can also use output variables from another stage. In this example, Stage B depends on a variable in Stage A.

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=shouldrun;isOutput=true]true"
     # or on Windows:
     # - script: echo ##vso[task.setvariable variable=shouldrun;isOutput=true]true
       name: printvar

- stage: B
  condition: and(succeeded(), eq(dependencies.A.outputs['A1.printvar.shouldrun'], 'true'))
  dependsOn: A
  jobs:
  - job: B1
    steps:
    - script: echo hello from Stage B