目前没有任意退出工作的方法,但是可以使用条件语句,如果较早的步骤失败,则可以允许跳过后续步骤:
jobs:
foo:
steps:
...
- name: Early exit
run: exit_with_success
- if: failure()
run: foo
- if: failure()
run: ...
...
这个想法是如果第一步失败,那么其余的步骤就会运行,但如果第一步没有失败,其余步骤就不会运行。
然而,需要注意的是,如果接下来的任何步骤失败,其后的步骤仍将运行,这可能是不可取的。
另一个选择是使用步骤输出来指示成功或失败:
jobs:
foo:
steps:
...
- id: s1
name: Early exit
run:
- id: s2
if: steps.s1.conclusion == 'failure'
run: foo
- id: s3
if: steps.s2.conclusion == 'success'
run: ...
...
这种方法效果不错,可以非常细致地控制允许运行哪些步骤以及何时运行,但是需要添加大量的条件语句,导致代码变得冗长。
另一种选择是创建两个作业:
jobs:
check:
outputs:
status: ${{ steps.early.conclusion }}
steps:
- id: early
name: Early exit
run:
work:
needs: check
if: needs.check.outputs.status == 'success'
steps:
- run: foo
- run: ...
...
通过将检查移到单独的作业中并让另一个作业等待并检查状态,可以非常好地解决最后一种方法。但是,如果您有更多的作业,则必须在每个作业中重复相同的检查。与在每个步骤中进行检查相比,这并不太糟糕。
注意:在最后一个示例中,您可以使用对象过滤器语法使check
作业依赖于多个步骤的输出,然后在进一步的作业中使用contains
函数确保没有任何步骤失败:
jobs:
check:
outputs:
status: ${{ join(steps.*.conclusion) }}
steps:
- id: early
name: Early exit
run:
- id: more_steps
name: Mooorreee
run:
work:
needs: check
if: !contains(needs.check.outputs.status, 'failure')
steps:
- run: foo
- run: ...
另外,请记住,“失败”和“成功”不是步骤可得出的唯一结论。请参见steps.<step id>.conclusion
了解其他可能的原因。