Help us understand the problem. What is going on with this article?

GitHub Actions のSlack通知の最適化

はじめに

以下のようなワークフローでいずれかが失敗した場合に一度だけSlackなどで通知することを考えます。

  • 複数のJOBが needs で依存している
  • matrix が使用されている
  • 特定の条件でのみ実行されるJOBが含まれる

例:lint → test → publish (タグ付与の場合のみ) → GitHub Releases作成

jobs:
  lint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      # ...

  test:
    name: Test
    needs: lint
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: ['11', '12']
    steps:
       # ...

  publish:
    name: Publish Package
    needs: test
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
       # ...

  release:
    name: Create GitHub Release
    needs: publish
    runs-on: ubuntu-latest
    steps:
      # ...

簡単そうだし機能としてあっても良さそうですが結構難しいです。

もともとやっていた方法

  • すべてのJOBのそれぞれのステップの最後に失敗した場合の通知を設定
  • 成功したときの通知も必要な場合は
    • 特定の条件でのみ実行されるJOBを除外
    • 通知用のJOBを最後に追加し needs を設定

先程の例では

jobs:
  lint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      # ...

      - uses: 8398a7/action-slack@v2
        with:
          status: failure
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  test:
    name: Test
    needs: lint
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: ['11', '12']
    steps:
       # ...

      - uses: 8398a7/action-slack@v2
        with:
          status: failure
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

  slack:
    name: Slack
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: 8398a7/action-slack@v2
        with:
          status: success
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

特定の条件でのみ実行されるJOBが入っているとSKIPされた際に通知用のJOBまで到達しません。
if: always() を通知用のJOBに設定すればSKIPされてもいずれかのJOBが失敗しても通知用のJOBが実行されますが、job.status は常に Success になります。
また、matrix ではそれぞれ失敗の通知が発行される問題もあります。

最近やっている方法

最近 GitHub Actions API が公開されました。
それを利用してワークフローの結果を取得する GitHub Actions を作成したのでそれを使用します。

https://github.com/technote-space/workflow-conclusion-action

jobs:
  lint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      # ...

  test:
    name: Test
    needs: lint
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: ['11', '12']
    steps:
       # ...

  publish:
    name: Publish Package
    needs: test
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
       # ...

  release:
    name: Create GitHub Release
    needs: publish
    runs-on: ubuntu-latest
    steps:
      # ...

  slack:
    name: Slack
    needs: release # 最後のJOBを指定
    runs-on: ubuntu-latest
    if: always() # alwaysを指定
    steps:
      - uses: technote-space/workflow-conclusion-action@v1 # Workflow の結果を取得するアクション
      - uses: 8398a7/action-slack@v2
        with:
          status: ${{ env.WORKFLOW_CONCLUSION }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

変更点は最後のJOBの追加のみです。
env.WORKFLOW_CONCLUSION には skipped, success, cancelled, failure のいずれかが設定されます。

いずれかのJOBが失敗した時のみ通知したい場合は通知用のJOBを以下のようにします。

  slack:
    name: Slack
    needs: release
    runs-on: ubuntu-latest
    if: always()
    steps:
      - uses: technote-space/workflow-conclusion-action@v1
      - uses: 8398a7/action-slack@v2
        with:
          status: failure
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        if: env.WORKFLOW_CONCLUSION == 'failure'

これで何回も通知用のステップを書く必要がなくなり、また matrix での失敗も複数送られることがなくなります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした