【问题标题】:How to put conditional job in need of another job in Github Action如何在 Github Action 中让有条件的工作需要另一份工作
【发布时间】:2021-09-01 14:17:59
【问题描述】:

以下是我的 GitHub 工作流程

name: APP Build
on:
  push:
    branches:
      - feature/test

jobs:
  test-1:
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test1') }}
    steps:
      - name: test-fail
        run: echo "test1"
  test-2:
    runs-on: ubuntu-latest
    if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test2') }}
    steps:
      - name: test-fail
        run: echo "test1"
  notify-slack:
    name: Slack Notification
    runs-on: ubuntu-latest
    needs: [test-1, test-2]
    steps:
      - name: Slack Notification
        uses: rtCamp/action-slack-notify@v2.2.0
        env:
          SLACK_CHANNEL: alert
          SLACK_COLOR: "${{ job.status == 'success' && 'good' || 'danger' }}"

问题:test1test2 根据我的提交消息,作业是有条件的,但通知 slack 需要 test1test2。我不能同时放两者,因为如果其中一个作业跳过notify-slack 也会跳过。如何使这项工作?

【问题讨论】:

    标签: github-actions


    【解决方案1】:

    Github about this 存在问题。您需要添加如下条件:

      test-1:
        runs-on: ubuntu-latest
        if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test1') }}
        steps:
          - name: test-fail
            run: echo "test1"
      test-2:
        runs-on: ubuntu-latest
        if: ${{ github.event_name == 'push' && contains( github.event.head_commit.message, 'test2') }}
        steps:
          - name: test-fail
            run: echo "test1"
      notify-slack:
        name: Slack Notification
        runs-on: ubuntu-latest
        needs: [test-1, test-2]
        if: |
          always() && 
          (needs.test-1.result == 'success' || needs.test-1.result == 'skipped') && 
          (needs.test-2.result == 'success' || needs.test-2.result == 'skipped') && 
          !(needs.test-1.result == 'skipped' && needs.test-2.result == 'skipped')
        steps:
          - name: Slack Notification
            uses: rtCamp/action-slack-notify@v2.2.0
            env:
              SLACK_CHANNEL: alert
              SLACK_COLOR: "${{ job.status == 'success' && 'good' || 'danger' }}"
    

    【讨论】:

    • 尝试了这个但是得到错误“你的 yaml 语法有错误”如果:| always() && (needs.check-environment.result == 'success' || needs.check-environment.result == 'skipped') && (needs.deploy.result == 'success' || needs.deploy.结果 == 'skipped') && (needs.restart-pods.result == 'success' || needs.restart-pods.result == 'skipped') && (github.event_name == 'pull_request')
    • 上述条件现在有效。前两个条件工作正常。如果其中一个工作成功,那么我们必须构建,但如果两个工作都跳过则跳过构建,但这种情况不能正常工作(needs.test-1.result !='skipped' && needs.test-2.result != '跳过')
    • 你说得对,我改变了条件。 (needs.test-1.result == 'success' || needs.test-2.result == 'success') 所以知道它应该在successskipped 之一时触发,但在success 都不是时不会触发。这是预期的行为吗?或者当两者都被跳过时我们也应该触发这一步?
    • 我修改了条件,现在它可以工作了。请在您的答案中更新此内容。 always() && (needs.test-1.result == 'success' || needs.test-1.result == 'skipped') && (needs.test-2.result == 'success' || 需要。 test-2.result == 'skipped') && !(needs.test-1.result == 'skipped' && needs.test-2.result == 'skipped')
    • 我更新了我的回复。很高兴您最终找到了解决问题的方法!
    【解决方案2】:

    可以使用以下工作流逻辑来实现这样的条件

    jobs:
      A:
        runs-on: ubuntu-latest
        steps:
          - run: echo "success always"
      B:
        runs-on: ubuntu-latest
        if: false
        steps:
          - run: echo "this will never run"
      C:
        runs-on: ubuntu-latest
        steps:
          - run: |
              exho "here to fail"
              exit 1
    
      D:
        runs-on: ubuntu-latest
        needs: [A, B, C]
        if: |
          always() &&
          !contains(needs.*.result, 'cancelled')
        # you can add conditions if needed e.g.
        # !contains(needs.*.result, 'failure')
        steps:
          - run: echo "${{ toJSON(needs) }}"
    

    您还需要修改 SLACK_COLOR 逻辑。 job.status == 'success' 将不起作用,因为无论任何依赖项是否失败,对于此作业,它将始终为 success。将needs 用于您的逻辑,例如工作D 输出是:

    {
      A: {
        result: success,
        outputs: {}
      },
      B: {
        result: skipped,
        outputs: {}
      },
      C: {
        result: failure,
        outputs: {}
      }
    }
    

    所以你SLACK_COLOR 可以这样设置

    SLACK_COLOR: "${{ contains(needs.*.result, 'failure') && 'danger' || 'good' }}"
    

    【讨论】:

    • 如果:| always() && !contains(needs.*.result, 'cancelled') 但是在这种情况下,如果 C 失败,那么它也会运行,因为我们使用 always()?
    • 如果您想在C 或任何依赖项失败时排除D 的执行,这是正确的,如果D always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') 的条件使用此条件
    猜你喜欢
    • 2021-10-26
    • 2021-03-27
    • 2021-12-28
    • 2016-01-28
    • 1970-01-01
    • 2021-10-20
    • 2021-09-10
    • 2019-12-24
    • 2021-01-13
    相关资源
    最近更新 更多