如何在 Github Actions 步骤中强制退出

Yoh*_*hei 23 github-actions

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

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: ...
 ...
Run Code Online (Sandbox Code Playgroud)

怎么做?

sma*_*c89 29

目前没有办法任意退出作业,但有一种方法可以在较早的步骤失败时跳过后续步骤,方法是使用条件

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: ...
 ...
Run Code Online (Sandbox Code Playgroud)

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

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


另一种选择是使用步骤输出来指示失败或成功:

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: ...
 ...
Run Code Online (Sandbox Code Playgroud)

这种方法效果很好,可以让您非常精细地控制允许运行哪些步骤以及何时运行,但是它变得非常冗长。


另一种选择是有两个工作:

  • 一种检查您的状况
  • 另一个取决于它:
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: ...
 ...
Run Code Online (Sandbox Code Playgroud)

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


注意:在最后一个示例中,您可以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: ...
Run Code Online (Sandbox Code Playgroud)

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

  • 对于 Github 现在应该简单提供的功能来说,这些都是创造性但不方便的解决方法。票在这里,请投票:https://github.com/actions/runner/issues/662 (4认同)

evg*_*hev 18

该行为可以通过和命令exit来实现:gh run cancelgh run watch

- name: Early exit
  run: |
    gh run cancel ${{ github.run_id }}
    gh run watch ${{ github.run_id }}
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Run Code Online (Sandbox Code Playgroud)

watch是必需的,因为取消不会立即中止。

您可能需要actions: 'write'为该工作添加权限,例如:

permissions:
  ...
  actions: 'write'
Run Code Online (Sandbox Code Playgroud)

  • 它取消了整个工作流程。并将整个工作流程标记为已取消 (5认同)
  • 正是我想要跳过步骤/作业并将其标记为已跳过,而不是成功或失败。+1 (3认同)
  • 感谢您提供这个解决方法。并不理想,因为它将工作流程标记为已取消并发送通知电子邮件,据我所知,我们无法抑制该通知电子邮件。 (2认同)
  • 有没有办法在取消后将工作流程标记为成功 (2认同)