Azure DevOps YAML管道中的有条件依赖作业

20
我正在使用YAML构建一个复杂的流水线,并尝试创建两个作业之间的依赖关系,使得后者仅在前者基于参数设置运行时才运行。我似乎无法理清楚这是否可行。 我的流水线定义如下:
parameters:
- name: doJobA
  type: boolean

stages:
  jobs:
  - job: JobA
    condition: eq('${{ parameters.doJobA }}', true)
    # ... details removed for brevity

  - job: JobB
    dependsOn: JobA
    # ... details removed for brevity
如果parameters.doJobA为真,则JobB应该在JobA之后运行,否则应立即运行。简单地添加dependsOn条件会导致JobA条件未满足时跳过JobB,这是有道理的,但我希望无论如何都能运行它。
是否可能以这种方式定义一个有条件的dependsOn
编辑:我遇到了另一个问题,使下面的解决方案无法使用。 我需要根据先前运行的PowerShell脚本设置的变量来确定条件,而不是基于参数。
4个回答

35

3

这是我编写的示例代码(您可以查看示例)。作业2始终运行,并且在作业1运行后运行。

更新的YAML

- job: One
  condition: eq('${{ parameters.DoJobOne }}', true)
  pool:
    vmImage: 'windows-2019'
  steps:
  - powershell: |
      throw "simulate Job One failing"
      echo "##vso[task.setvariable variable=JobOneRan;isOutput=true]true"
    name: setvarStep
  - script: |
      echo $(setvarStep.JobOneRan)          
    name: echovariable


- job: Two
  condition: and(always(), eq('${{ parameters.DoJobOne }}', eq(dependencies.One.outputs['setvarStep.JobOneRan'], true)))
  dependsOn: One
  pool:
    vmImage: 'windows-2019'
  variables:
    myVariableFromJobOne: $[ dependencies.One.outputs['setvarStep.JobOneRan'] ]
  steps:
  - script: echo $(myVariableFromJobOne)
    name: echovariable

希望这能有所帮助。
Wes

我认为这并没有解决原问题,即只有在Job 1运行的条件下才运行Job 2。 - DreadedFrost
如果任务1失败,这样做不会一直运行任务2吗? - Thomas
如果作业1失败,作业2将运行。我对要求的理解是:“如果parameters.doJobA为true,则在JobA之后运行JobB,如果parameters.doJobA为false,则立即运行JobB。” - Wes MacDonald
感谢更新,Wes。虽然答案需要每个作业通过一些脚本设置变量,但我认为这非常优雅。 - Thomas
在查找此问题时,我刚刚看到现在有一个更简单的解决方案:https://dev59.com/N1IG5IYBdhLWcg3w9W3d#63992994 - Arne Klein

2

我找到了一个稍微不太优雅的解决方案。通过将表达式与布尔参数组合,我能够做到我需要的事情,但有点棘手:

parameters:
- name: doJobA
  type: boolean

stages:
  jobs:
  - job: JobA
    condition: eq('${{ parameters.doJobA }}', true)
    # ... details removed for brevity

  - job: JobB
    ${{ if eq(parameters.doJobA, true) }}:
      dependsOn: JobA
      condition: succeeded()
    # ... details removed for brevity

如果参数doJobA为真,我在此处插入一个依赖从句。否则,它不存在。为了确保只有在存在dependsOn的情况下才添加条件,以便JobB仅在JobA成功运行时运行,但是需要添加条件。

结果是,如果doJobA为false,则作业立即运行,因为生成的yaml不包含任何dependsOncondition条目,但在其他情况下,它将取决于成功执行JobA

然而,我仍然希望能有更好的方法来实现这一点,因为这似乎有点复杂(我个人认为)。

编辑:此解决方案仅适用于静态属性而不是动态变量。


感谢您在这里分享您的解决方案,您能否将您的解决方案接受为答案呢?这对于遇到相同问题的其他成员来说会很有帮助,让他们更容易地找到解决方案。祝您拥有愉快的一天 :) - Hugh Lin
1
不幸的是,就像我在初始问题的编辑中所写的那样,这并没有解决我的问题。这个解决方案只适用于静态属性,而不是我需要的动态设置变量,以使我的模板正常工作。如果您有任何建议,我将非常感激! - Thomas
这种方法对我非常成功,我唯一做出的更改是定义了一个表达式来表示当doJobA为false时。 - Nick Graham

1
以下解决方案适用于您的JobA参数为字符串的情况。(布尔参数也适用)
parameters:
- name: doJobA
  type: string

stages:
  jobs:
  - job: JobA
    condition: eq('${{ parameters.doJobA }}', 'string')
    # ... details removed for brevity

  - job: JobB
    dependsOn: JobA
    condition: or(
                  and(succeeded(), eq('${{ parameters. doJobA }}', 'yourstring')), 
                  and(always(), ne('${{ parameters. doJobA }}', 'yourstring'))
                )

    # ... details removed for brevity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接