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

I'm having trouble with what to do when my tests fail though. This is my action. When my tests pass everything works great, my results are zipped an exported as an artifact, but if my tests fail, it stops the rest of the steps in the job, so my results never get published. I tried adding the 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 This makes it continue after it fails and uploads my test results. but then the job is marked as passed, even though my test step failed. Is there some way to have it upload my artifact even if a step fails, while still marking the overall job as failed?

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

你可以添加

if: always()

到您的步骤,即使前一个步骤失败,也可以运行它 https://docs.github.com/en/actions/learn-github-actions/expressions#status-check-functions

所以对于单个步骤,它看起来是这样的:

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

- name: Archive Test Results
  if: always()
  uses: actions/upload-artifact@v1
  with:
    name: test-results
    path: app/build

或者你可以把它添加到一个工作中:

jobs:
  job1:
  job2:
    needs: job1
  job3:
    if: always()
    needs: [job1, job2]

此外,正如下面所指出的,放置always()将导致即使取消构建也能运行函数。 如果你不想在手动取消作业时运行该函数,你可以输入:

if: success() || failure()

Addon: if you have following sitution. 2 steps i.e. build > deploy and in some cases i.e. workflow_dispatch with input parameters you might want to skip build and proceed with deploy. At the same time you might want deploy to be skipped, when build failed. Logically that would be something like skipped or not failed as deploy conditional. if: always() will not work, cause it will always trigger deploy, even if build failed. Solution is pretty simple: if: ${{ !failure() }} Mind that you cannot skip brackets when negating in if:, cause it reports syntax error.


另外,你可以添加continue-on-error: true。 看起来像

- name: Job fail
  continue-on-error: true
  run |
    exit 1
- name: Next job
  run |
    echo Hello

在这里阅读更多。


您可以添加|| true到您的命令中。 例子:

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

运行一个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

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

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

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

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

注意: 文档明确感谢Vladimir Panteleev,他在其中提交了以下PR: Github Docs PR #8411


这里的其他答案都很好,但您可能需要更细一点的粒度。

例如,只有在./test运行时才执行./upload,即使它失败了。 但是,如果有其他故障并阻止测试运行,则不要上传。

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

步骤。*。结论可能是成功、失败、取消或跳过。 成功或失败表示运行的步骤。Cancelled或skip表示没有发生。

注意,这里有一个重要的警告,您必须在if中测试至少一个success()或failure()。 如果:steps.test.conclusion == 'success' || steps.test.conclusion == 'failure'将不能正常工作。