如何运行 github-actions 步骤,即使上一步失败,但仍使作业失败
Posted
技术标签:
【中文标题】如何运行 github-actions 步骤,即使上一步失败,但仍使作业失败【英文标题】:How to run a github-actions step, even if the previous step fails, while still failing the job 【发布时间】:2020-03-10 12:13:16 【问题描述】:我正在尝试按照 Github 的示例使用 github 操作测试我的构建,然后压缩测试结果并将它们作为工件上传。 https://help.github.com/en/actions/automating-your-workflow-with-github-actions/persisting-workflow-data-using-artifacts#uploading-build-and-test-artifacts
但是,当我的测试失败时,我不知道该怎么做。这是我的行动。当我的测试通过时一切正常,我的结果被压缩并导出为工件,但如果我的测试失败,它会停止工作中的其余步骤,所以我的结果永远不会被发布。 我尝试添加 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
【问题讨论】:
您可能还想查看continue-on-error
。我对此没有太多经验,但是如果您不想担心特定job
或step
中的错误,您可以使用continue-on-error: true
来允许失败而不标记整个@987654330 @/workflow
为失败。
【参考方案1】:
你可以添加
if: always()
即使上一步失败,也可以运行它 https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#job-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()
或 failure()
,否则似乎总是隐含 if: success()
- 即使您设置了例如if: true
。这意味着(也许令人惊讶)if: x
与 if: always() && x
的不同之处在于,如果前面的步骤失败或作业被取消,第一个将不会运行。
文档中的一条注释:“当您在 if 条件中使用表达式时,您可以省略表达式语法 ($
),因为 GitHub 会自动将 if 条件评估为表达式。”换句话说,可以简单地使用:if: always()
.
我向 GitHub 文档提交了 PR 以澄清这一点:github.com/github/docs/pull/8411
请注意,这会产生您无法再手动取消工作流程的副作用:docs.github.com/en/actions/managing-workflow-runs/…
与if: always()
相反,if: success() || failure()
保留了取消构建的能力,同时仍然实现了 OPs 目标。【参考方案2】:
其他方式,您可以添加continue-on-error: true
。
看起来像
- name: Job fail
continue-on-error: true
run |
exit 1
- name: Next job
run |
echo Hello
在here阅读更多内容。
【讨论】:
我在原始问题中描述了该解决方案,但这在我的情况下不起作用,因为使用 continue-on-error,失败的任务仍然会导致整个构建通过。而且我仍然希望将失败的构建标记为失败,同时仍然运行此任务,而不管以前的任务如何。如果您不关心整体构建状态,则此解决方案将起作用。 @TomerShemesh 这是我在谷歌上搜索的解决方案! @TomerShemesh 我有完全相同的问题,但if: always
和continue-on-error: true
都对我不起作用。如果测试失败,您是否在每个跳过的步骤中都使用了if: always
?
@Rsaleh 是的,我添加了 if:always 到我需要运行的每一步,即使出现故障。【参考方案3】:
插件:如果您有以下情况。 2个步骤,即build > deploy
,在某些情况下,即workflow_dispatch
,带有输入参数,您可能想跳过build
并继续deploy
。同时,当build
失败时,您可能希望跳过deploy
。
从逻辑上讲,这将类似于 skipped or not failed
作为 deploy
条件。if: always()
将不起作用,因为它总是会触发 deploy
,即使 build
失败。
解决方法很简单:if: $ !failure()
注意if:
中取反时不能跳过括号,否则会报语法错误。
【讨论】:
【参考方案4】:你可以添加||忠于你的命令。 示例:
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Test App
run: ./gradlew test || true
【讨论】:
这不是一个很好的解决方案,因为测试的步骤将始终被标记为通过,即使测试失败。这不是人们通常想要的结果。您仍然希望步骤本身失败并将构建本身标记为失败,但仍希望运行诸如归档和发布测试结果之类的任务。无论测试步骤本身是否通过,您都想要执行此操作。执行您的建议将导致所有构建始终通过,无论测试是否失败。以上是关于如何运行 github-actions 步骤,即使上一步失败,但仍使作业失败的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Github-actions 在 Docker 上使用 Mysql 运行 Prisma 迁移
vue-cli3携手rollup、github-actions打造自动部署的vue组件模板(使用篇)
[,foreach和github-actions中的其他循环