gpt4 book ai didi

azure-devops - 使用 'each' 在 Azure DevOps 中构建条件

转载 作者:行者123 更新时间:2023-12-05 06:11:40 25 4
gpt4 key购买 nike

在 Azure DevOps(YAML 管道)中,我们有一个阶段,只有在跳过另一组阶段后才能运行。

在下面的示例中,用户可以在触发手动运行时修改参数 copyStages_UAT,这意味着不可能对 dependsOn条件进行硬编码 属性,因此需要使用指令 each

- template: ../Stages/stage--code--depoly-to-environment.yml
parameters:
name: Deploy_PRD_UKS
displayName: Deploy PRD - UK South
dependsOn:
- ${{ each uatStage in parameters.copyStages_UAT }}:
- Roll_Back_${{ uatStage.name }}
variables:
- template: ../Variables/variables--code--global.yml
- template: ../Variables/variables--code--prd.yml
environment: PRD

上面的这个阶段在管道中工作,但是因为成功运行会导致 dependsOn 中定义的阶段被跳过,遗憾的是 Azure DevOps 也将跳过这个阶段。

为了解决这个问题,我尝试添加一个条件 来检查前面的阶段是否都被跳过了。

condition: >-
and(replace(
${{ each uatStage in parameters.copyStages_UAT }}:
eq(dependencies.Roll_Back_${{ uatStage.name }}.result, 'Skipped'),
), ', )', ' )')

不幸的是,似乎我不能在这种情况下使用指令 each -

The directive 'each' is not allowed in this context. Directives are not supported for expressions that are embedded within a string. Directives are only supported when the entire value is an expression.

由于 condition 只能是字符串,我如何利用表达式和/或指令来构造我想要的条件?

所需 YAML 示例

假设为参数 copyStages_UAT 提供了以下值 -

- name: UAT_UKS
displayName: UAT - UK South
- name: UAT_UKW
displayName: UAT - UK West

YAML 应该是这样编译的。我不担心条件的格式,只要包含相关检查即可。

- template: ../Stages/stage--code--depoly-to-environment.yml
parameters:
name: Deploy_PRD_UKS
displayName: Deploy PRD - UK South
dependsOn:
- Roll_Back_UAT_UKS
- Roll_Back_UAT_UKW
condition: >-
and(
eq(dependencies.Roll_Back_UAT_UKS.result, 'Skipped'),
eq(dependencies.Roll_Back_UAT_UKW.result, 'Skipped')
)
variables:
- template: ../Variables/variables--code--global.yml
- template: ../Variables/variables--code--prd.yml
environment: PRD

最佳答案

Azure DevOps Pipelines 没有特别好的方法来解决这个问题。但是,和(...)join(delimiter, ...)'Filtered Arrays'可以用来 hackily 完成此操作。


观察以下条件可以重新排列:

and(
eq(dependencies.Roll_Back_UAT_UKW.result, 'Skipped'),
eq(dependencies.Roll_Back_UAT_UKX.result, 'Skipped'),
eq(dependencies.Roll_Back_UAT_UKY.result, 'Skipped'),
eq(dependencies.Roll_Back_UAT_UKZ.result, 'Skipped')
)
and(
eq(dependencies.Roll_Back_
UAT_UKW
.result, 'Skipped'), eq(dependencies.Roll_Back_
UAT_UKX
.result, 'Skipped'), eq(dependencies.Roll_Back_
UAT_UKY
.result, 'Skipped'), eq(dependencies.Roll_Back_
UAT_UKZ
.result, 'Skipped')
)

或者更抽象地说,PREFIX=eq(dependencies.Roll_Back_ and SUFFIX=.result, 'Skipped'):

and(
<PREFIX>
UAT_UKW
<SUFFIX>, <PREFIX>
UAT_UKX
<SUFFIX>, <PREFIX>
UAT_UKY
<SUFFIX>, <PREFIX>
UAT_UKZ
<SUFFIX>
)

使用过滤数组 (NAMES=parameters.parameterName.*.name) 来提取名称,然后可以编写聚合:

and(<PREFIX>${{ join('<PREFIX>, <SUFFIX>', <NAMES>) }}<SUFFIX>)

因此:

condition: |
and(
ne(dependencies.Roll_Back_${{ join('.result, ''Skipped''), ne(dependencies.Roll_Back_', parameters.copyStages_UAT.*.name) }}.result, 'Skipped')
)

但是有一些明显的警告:

  • 如果 parameters.copyStages_UAT 中有 0 个元素,则表达式的计算结果为 and(dependencies.Roll_Back_.result, 'Skipped') 这可能不合情理。

  • and(...) 需要至少 2 个参数,因此如果只有 0 或 1 个表达式,这可能会失败。为了避免这种情况,可以提供 True 作为第一个和第二个参数,这样表达式始终有效。如果您的逻辑需要 or(...),则使用 False 而不是 True 以保持含义一致。

因此,您可能需要通过修改检查来防止这些情况发生:

${{ if eq(length(parameters.copyStages_UAT), 0) }}:
condition: false
${{ else }}:
condition: |
and(
True,
ne(dependencies.Roll_Back_${{ join('.result, ''Skipped''), ne(dependencies.Roll_Back_', parameters.copyStages_UAT.*.name) }}.result, 'Skipped')
)

关于azure-devops - 使用 'each' 在 Azure DevOps 中构建条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63904345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com