如何运行 github-actions 步骤,即使上一步失败,但仍无法完成作业

Tom*_*esh 57 github github-actions

我正在尝试遵循 Github 使用 github 操作测试我的构建的示例,然后压缩测试结果并将它们作为工件上传。 https://help.github.com/en/actions/automating-your-workflow-with-github-actions/persisting-workflow-data-using-artifacts#uploading-build-and-test-artifacts

但是,当我的测试失败时,我该怎么办。这是我的行动。当我的测试通过一切正常时,我的结果会被压缩并导出为工件,但如果我的测试失败,它会停止工作中的其余步骤,因此我的结果永远不会发布。
github-ci-result
我尝试添加 continue-on-error: true https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepscontinue-on -error
这使它在失败后继续并上传我的测试结果。但是即使我的测试步骤失败,该作业也被标记为通过。有没有办法让它上传我的工件,即使一个步骤失败,同时仍然将整个工作标记为失败?

name: CI
on:
  pull_request:
    branches:
    - master
  push:
    branches:
      - master

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1    
    - name: Test App
      run: ./gradlew test

    - name: Archive Rest Results
      uses: actions/upload-artifact@v1
      with:
        name: test-results
        path: app/build/reports/tests
Run Code Online (Sandbox Code Playgroud)

小智 73

其他方式,您可以添加continue-on-error: true. 看起来像

- name: Job fail
  continue-on-error: true
  run: |
    exit 1
- name: Next job
  run: |
    echo Hello
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多内容。

修复了缺少冒号的代码run

  • 我在最初的问题中描述了该解决方案,但这在我的情况下不起作用,因为在错误继续的情况下,失败的任务仍然会导致整体构建通过。而且我仍然希望将失败的构建标记为失败,同时无论之前的任务如何,仍然运行此任务。如果您不关心整体构建状态,则此解决方案将起作用。 (39认同)
  • @TomerShemesh,这是我在谷歌上搜索的解决方案! (5认同)

Tom*_*esh 71

你可以加

if: always()
Run Code Online (Sandbox Code Playgroud)

即使上一步失败,也可以运行它的步骤 https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github -actions#job-status-check-functions

  • 与“if:always()”相反,“if:success()||” failure()` 保留了取消构建的能力,同时仍然实现了 OP 目标。 (25认同)
  • 请注意,似乎总是隐含“if: success()”,除非您指定“always()”或“failure()” - 即使您设置了“if: true”。这意味着(也许令人惊讶)“if: x”与“if:always() && x”不同,如果前面的步骤失败或作业被取消,第一个将不会运行。 (12认同)
  • 请注意,这会带来不必要的副作用,您无法再手动取消工作流程:https://docs.github.com/en/actions/managing-workflow-runs/canceling-a-workflow#steps-github-takes-取消工作流程运行 (6认同)
  • 文档中的一条注释:“当您在 if 条件中使用表达式时,您可以省略表达式语法 (`${{ }}`),因为 GitHub 会自动将 if 条件计算为表达式。” 换句话说,我们可以简单地使用:“if:always()”。 (4认同)
  • 我向 GitHub 文档提交了 PR 来澄清这一点:https://github.com/github/docs/pull/8411 (3认同)

U-w*_*ays 29

运行 github-actions 步骤,即使上一步失败

如果您只需要在成功失败时执行该步骤,则:

steps:
- name: Build App
  run: ./build.sh

- name: Archive Test Results
  if: success() || failure()
  uses: actions/upload-artifact@v1
  with:
    name: test-results
    path: app/build
Run Code Online (Sandbox Code Playgroud)

为什么使用success() || failure()而不是always()

阅读Github 上的状态检查函数文档:

总是

导致步骤始终执行,并返回 true,即使已取消。当严重故障阻止任务运行时,作业或步骤将不会运行。例如,如果获取源失败。

这意味着即使作业被取消,它也会运行,如果这是您想要的,那就继续吧。不然的话success() || failure()会更合适。

注意- 感谢Vladimir Panteleev,他在其中提交了以下 PR:Github Docs PR #8411,使文档变得清晰


Cam*_*ind 18

这里的其他答案都很棒并且有效,但您可能需要更详细的信息。

例如,./upload只有./test跑了,即使失败了。
但是,如果其他原因失败并阻止测试运行,请不要上传。

      # ... Other steps
      - run: ./test
        id: test
      - run: ./upload
        if: success() || steps.test.conclusion == 'failure'
Run Code Online (Sandbox Code Playgroud)

steps.*.conclusion将是success, failure, cancelled, 或skipped
successfailure指示运行的步骤。cancelled或者skipped意味着没有。

请注意,有一个重要的警告,您必须success()在. 不会按预期工作。failure()if
if: steps.test.conclusion == 'success' || steps.test.conclusion == 'failure'


she*_*ekh 12

插件:如果您有以下情况。2 个步骤,即build > deploy在某些情况下,即workflow_dispatch使用输入参数时,您可能希望跳过build并继续deploy。同时,deploy当失败时,您可能希望被跳过build
从逻辑上讲,这就像有条件的skipped or not failed一样deploy
if: always()不会工作,因为它总是会触发deploy,即使build失败了。
解决方案非常简单:
if: ${{ !failure() }}
请注意,在 in 中求反时不能跳过括号if:,因为它会报告语法错误。


use*_*610 6

代替

if: success() || failure()
Run Code Online (Sandbox Code Playgroud)

我建议使用

if: ${{ ! cancelled() }}
Run Code Online (Sandbox Code Playgroud)

“始终运行步骤,除非 CI 运行被取消”。我的版本更简洁,并且在我看来不那么尴尬。

参考:https ://docs.github.com/en/actions/learn-github-actions/expressions#status-check-functions