问题描述
在Azure DevOps中的一个流水线中,当还没有运行任何阶段时,Agent.JobStatus
的值是什么?它是否被初始化为’Succeeded’,还是最初未定义或设置为null之类的,只有在第一次成功执行之后才被设置为’Succeeded’?
换句话说:
– 如果我在第一个阶段的运行条件中使用了succeeded()
(与in(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues')
相同),即使没有前面的阶段返回成功的结果,它是否会返回true?
– 如果我在第二个阶段的条件中使用succeeded()
,而第一个阶段的条件计算为false,因此第一个阶段被跳过,即使没有前面的阶段被执行并返回成功的结果,它是否会返回true?
我想理解的方式是,在下面的代码中,succeeded
将在我使用它的这两个位置都返回true
。在这段代码中,如果原始触发的仓库分支是’main’,我希望第一个阶段运行,如果原始分支是’release/*’,则第二个阶段运行。(这是实际逻辑的略微简化版本。)我理解的正确吗?
stages:
- template: my-template.yml
condition: and(succeeded(), eq(variables['resources.pipeline.previousPipeline.SourceBranch'], 'refs/heads/main'))
parameters:
...
- template: my-template.yml
condition: and(succeeded(), startsWith(variables['resources.pipeline.previousPipeline.SourceBranch'], 'refs/heads/release/'))
parameters:
...
或者,如果succeeded()
不以这种方式工作,如果我改用not(failed())
,我会得到我需要的结果吗?
解决方案
在Azure DevOps中,succeeded()
函数的行为确实是在阶段被执行后才设置结果的。因此,当你尝试在第一个阶段的条件中使用succeeded()
函数时,它实际上会返回false
,因为在这个时候还没有执行任何阶段。
如果你想在第一个阶段的条件中根据前面的阶段是否成功来判断是否运行,可以使用not(failed())
函数。这是因为即使前面的阶段被跳过,也不会将其标记为失败状态,因此你可以使用这个条件来确保在前面的阶段没有失败的情况下运行当前阶段。
下面是你可以应用在你的情况中的解决方案:
stages:
- template: my-template.yml
condition: and(not(failed()), eq(variables['resources.pipeline.previousPipeline.SourceBranch'], 'refs/heads/main'))
parameters:
...
- template: my-template.yml
condition: and(not(failed()), startsWith(variables['resources.pipeline.previousPipeline.SourceBranch'], 'refs/heads/release/'))
parameters:
...
通过使用not(failed())
,你可以更准确地控制在前面的阶段没有失败时运行当前阶段。这将确保你的流水线在逻辑上正确地执行。
请注意,succeeded()
函数和not(failed())
函数之间的区别在于,前者仅在阶段被执行后才设置为true
,而后者则在前面的阶段没有失败时为true
。根据你的描述,使用not(failed())
是更适合的选择,以满足你的需求。