【问题标题】:Azure DevOps Conditional execution of Job that depends on a Job in another StageAzure DevOps 有条件地执行依赖于另一个阶段中的作业的作业
【发布时间】:2020-02-12 11:07:13
【问题描述】:

我有一个看起来像这样的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 有两个工作 bc。我希望仅在作业 a 执行后才执行作业 c。我尝试通过将作业 a 中的变量 doThing 设置为是,然后在作业 c 中检查此变量。

但我得到一个错误:

阶段计划作业 c 依赖于未知作业 a

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

您对如何使其正常工作有什么建议吗?

【问题讨论】:

    标签: azure-devops conditional-statements azure-pipelines multistage-pipeline


    【解决方案1】:

    虽然 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)
    
    

    【讨论】:

      【解决方案2】:

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

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

      您目前无法指定阶段运行基于 输出变量设置在前一阶段。

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

      - stage: B
        dependsOn: A
      

      【讨论】:

      • 好吧,这就是我的怀疑。我将需要修改管道中的逻辑以实现相同的功能。不过我很好奇。你有什么解释为什么不允许这样做吗?
      • 它仍然准确吗?我在链接的文档中找不到这样的声明。
      • @ravenwing - 找到了解决方案并发布了here
      【解决方案3】:

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

      第一个是job-to-job dependencies across stages

      来自微软:

      在此示例中,无论作业 A1 成功还是跳过,作业 B1 都会运行。作业 B2 将检查作业 A1 的输出变量的值以确定它是否应该运行。

      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

      来自微软网站:

      阶段也可以使用来自另一个阶段的输出变量。在此示例中,阶段 B 依赖于阶段 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
      

      【讨论】:

        猜你喜欢
        • 2020-09-15
        • 1970-01-01
        • 2021-03-20
        • 1970-01-01
        • 2017-03-21
        • 2017-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多