我在 GitHub 操作作业中有以下步骤的顺序(第一个或多或少用于调试目的)
env:
FAIL_OUTCOME: 'fail'
- name: debug
shell: bash
run: |
echo "evaluation-1 result is ${{ steps.evaluation_1.outputs.evaluation-1-outcome }}
echo "evaluation-2 result is ${{ steps.evaluation_2.outputs.evaluation-2-outcome }}
echo $FAIL_OUTCOME
- name: send slack failure
if: ${{ steps.evaluation_1.outputs.evaluation-1-outcome }} == $FAIL_OUTCOME || ${{ steps.evaluation_2.outputs.evaluation-2-outcome }} == $FAIL_OUTCOME
uses: rtCamp/action-slack-notify@v2
env:
...
- name: send slack success
if: ${{ steps.evaluation_1.outputs.evaluation-1-outcome }} != $FAIL_OUTCOME && ${{ steps.evaluation_2.outputs.evaluation-2-outcome}} != $FAIL_OUTCOME
uses: rtCamp/action-slack-notify@v2
env:
...
以下是调试操作的结果:
echo "evaluation-1 result is
echo "evaluation-2 result is fail
似乎没有确定第一个结果的地方。
然而,让我困惑的是,成功行动也被执行,即
${{ steps.evaluation_1.outputs.evaluation-1-outcome }} != $FAIL_OUTCOME && ${{ steps.evaluation_2.outputs.evaluation-2-outcome}} != $FAIL_OUTCOME
成为现实。怎么可能?
为了提供更多上下文,前面步骤中的输出分配如下所示:
echo "::set-output name=evaluation-2-outcome::$FAIL_OUTCOME"
你的问题的直接答案是你在if
语句中滥用了$FAIL_OUTCOME
值。
在那里你需要使用:
if: steps.evaluation_1.outputs.evaluation-1-outcome == env.FAIL_OUTCOME || steps.evaluation_2.outputs.evaluation-2-outcome == env.FAIL_OUTCOME
...
if: steps.evaluation_1.outputs.evaluation-1-outcome != env.FAIL_OUTCOME && steps.evaluation_2.outputs.evaluation-2-outcome != env.FAIL_OUTCOME
或:
if: ${{ steps.evaluation_1.outputs.evaluation-1-outcome == env.FAIL_OUTCOME || steps.evaluation_2.outputs.evaluation-2-outcome == env.FAIL_OUTCOME }}
...
if: ${{ steps.evaluation_1.outputs.evaluation-1-outcome != env.FAIL_OUTCOME && steps.evaluation_2.outputs.evaluation-2-outcome != env.FAIL_OUTCOME }}
Env 变量只能在bash
范围内作为 $FAIL_OUTCOME 访问 - 在其他任何地方,您都需要显式使用env.
前缀。
但是,我建议正确执行此操作,而不是与 env 变量结合set-output
疯狂作斗争 - 这有很多陷阱,很难调试和维护。
通过检查整个作业的输出,可以轻松处理松弛成功和失败:
- name: send slack failure
if: failure()
- name: send slack success
if: success()
如果您只想就某些步骤的失败进行沟通:
notify_failure:
if: always() && !cancelled() && needs.check_failure_step.result != 'success'
needs: check_failure_step
而不是使用echo set-output::
只是exit 1
失败某项工作。 将其与needs
和工作输出值相结合,if: always()
您可以实现任何您想要的东西。
它还为您提供了一个巨大的优势,可以在工作流运行摘要上直接查看哪个作业失败,而无需查看其"输出"或"调试"日志。