3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GitHubアクションでエラーハンドリングしたかったら自作するしかなさそう

Last updated at Posted at 2019-07-21

注意

2020/02/08追記
この記事はGitHub Actions v1の話で、今のv2とは全く違う内容になっておりますm(_ _)m
エラーハンドリングについてもv2になってからはif: failure()とかで失敗時にタスクを実行みたいな設定が出来るようになりました!これでSlack通知のためにエラーハンドリングをしなくて良くなりました^^


始めに

今までCircleCIやCodeBuildを使ってきましたが、最近GitHubアクションも使ってみました。その際にエラー通知を実装しようとしたらかなり苦戦してしまったためそれについて記事にしました。

エラーハンドリングする術がない

GitHubアクションのステータスはWeb上では確認でき、check_suiteなどのイベントでフックできると書いてあります。

pushイベントでビルドとデプロイを実行し、check_suiteでステータスをみてSlack通知する方法を考えていたのですが、なぜかcheck_suiteのイベントはフックされませんでした。
結論から言うとGitHubアクションで実行した処理はイベントのフック対象にはならないです。pushイベントでgh-pagesブランチにpushしても再度pushイベントはフックされないといった感じです。

アクションが失敗した場合は次のアクションは実行されませんので、エラーをハンドリングする方法はないと思った方が良さそうです。
ちなみにcheck_suiteは他のCIを実行した時にイベントをハンドリングすることはできました(あんまり意味がない気がしますが・・・)

それでもエラーハンドリングをしたい場合

アクションを順番に実行するとエラーハンドリングできなくなってしまうので、一つのアクションで全部書くしかないかなと思っています。
僕は以下のようにアクションを自前で定義してそれだけを呼ぶようにしています。自前でshellを書くとtrapを使ってtry-catchっぽくかけるので、それで成功とエラー通知をすることができます。

.github/main.workflow
workflow "Build and Deploy" {
  on = "push"
  resolves = ["main"]
}

action "main" {
  uses = "./.github/action/"
  secrets = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
}
.github/action/entrypoint.sh
# !/bin/bash

# ========== メソッドとエラーハンドリングの設定 ===========

# Slack通知メソッド
function notify() {
  if [ $1 = "SUCCESS" ]; then
    STATUS_COLOR="good"
    STATUS_TEXT="SUCCESS"
  else
    STATUS_COLOR="danger"
    STATUS_TEXT="FAILED"
  fi

  JSON=$(cat << EOS
{
  "attachments": [
    {
      "title": "${GITHUB_REPOSITORY}",
      "title_link": "${ACTION_URL}",
      "color": "${STATUS_COLOR}",
      "fields": [
        { "title": "STATUS", "value": "${STATUS_TEXT}", "short": "true" }
      ]
    }
  ]
}
EOS
)

  RES=`curl -s -X POST -H 'Content-Type: application/json' -d "${JSON}" ${SLACK_WEBHOOK_API_URL}`

  echo $RES
}

# catchメソッド
function catch() {
  notify ERROR
}

# エラーした時にcatchメソッドを呼ぶように設定
set -e
trap catch ERR

# ========== メイン処理 ==========

# Slack通知のURL
SLACK_WEBHOOK_API_URL=[WebHook URL]

# ActionのURL
ACTION_URL=https://github.com/$GITHUB_REPOSITORY/actions

# インストールとビルド
yarn install
yarn build

# S3にアップロード
aws s3 sync ./dist/ s3://bucket-name --exact-timestamps --delete

# Slackに成功を通知する
notify SUCCESS

終わりに

GitHubアクションはやり方が分かると結構使いやすそうな印象でしたが、エラーハンドリングはかなり厳しそうでした。エラーハンドリングをするなら他のアクションを使うのはほぼ無理な気がしました。
小さなモジュールを組み合わせていくという発想は良さそうに見えますが、その分毎回Dockerの起動をさせられてオーバーヘッドがかかったり、ちょっとした文字列加工をしてもその変数を引き継ぐ術がなかったり、細かいことをやろうとすると結構やりづらかったです。
こういった問題はアクションを自作して一つのshellにしてしまえば解決するのですが、GitHubアクションの特徴を殺してしまっている気がしてならないですね・・・。

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?