【问题标题】:How to force to exit in Github Actions step如何在 Github Actions 步骤中强制退出
【发布时间】:2023-03-31 03:49:01
【问题描述】:

如果满足特定条件,我想退出工作:

jobs:
  foo:
    steps:
      ...
      - name: Early exit
        run: exit_with_success # I want to know what command I should write here
        if: true
      - run: foo
      - run: ...
 ...

怎么做?

【问题讨论】:

标签: github-actions


【解决方案1】:

目前无法任意退出作业,但有一种方法可以在前一步失败时跳过后续步骤,使用conditionals

jobs:
  foo:
    steps:
      ...
      - name: Early exit
        run: exit_with_success # I want to know what command I should write here
      - if: failure()
        run: foo
      - if: failure()
        run: ...
 ...

这个想法是,如果第一步失败,那么其余的将运行,但如果第一步没有失败,其余的将不会运行。

但是,需要注意的是,如果任何后续步骤失败,它们之后的步骤仍将运行,这可能是可取的,也可能不是可取的。


另一种选择是使用step outputs 表示失败或成功:

jobs:
  foo:
    steps:
      ...
      - id: s1
        name: Early exit
        run: # exit_with_success
      - 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: # exit_with_success
  work:
    needs: check
    if: needs.check.outputs.status == 'success'
    steps:
      - run: foo
      - run: ...
 ...

通过将检查移至单独的作业并让另一个作业等待并检查状态,最后一种方法非常有效。但是,如果您有更多工作,则必须在每个工作中重复相同的检查。与在每个步骤中进行检查相比,这还不错。


注意:在最后一个示例中,您可以使用 object filter 语法让 check 作业依赖于多个步骤的输出,然后使用contains 在进一步的工作中发挥作用,以确保没有任何步骤失败:

jobs:
  check:
    outputs:
      status: ${{ join(steps.*.conclusion) }}
    steps:
      - id: early
        name: Early exit
        run: # exit_with_success
      - id: more_steps
        name: Mooorreee
        run: # exit_maybe_with_success
  work:
    needs: check
    if: !contains(needs.check.outputs.status, 'failure')
    steps:
      - run: foo
      - run: ...

此外,请记住,“失败”和“成功”并不是从某个步骤中得出的唯一结论。其他可能的原因请参见steps.<step id>.conclusion

【讨论】:

  • 我尝试了对象过滤语法。但是,我使用的是策略矩阵,而您的通配符代码不起作用。我在文档中没有发现任何与此相关的内容。你知道策略矩阵有什么不同吗?作为参考,我收到此错误Error: Fail to evaluate job outputs Error: The template is not valid. .github/workflows/build.yml (Line: 54, Col: 19): A sequence was not expected
  • @It'sK 这有点道理,因为steps.*.conclusion 将评估为一个结论列表,而docs 声明输出必须是一个字符串。尝试将其更改为join(steps.*.conclusion),看看是否适合您。让我知道,以便我可以正确更新答案
  • 我已经测试过,但奇怪的是,join(steps.*.conclusion) 的多个步骤的输出结果仅为success。没有得到每一步的结论。仅供参考,一步成功,一步失败,跳过一步。
  • @It'sK 这听起来像是一个错误。可以的话请举报
猜你喜欢
  • 2020-03-30
  • 2021-12-29
  • 1970-01-01
  • 2020-01-11
  • 2020-11-28
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
  • 2020-01-09
相关资源
最近更新 更多