Jenkinsでのデプロイ完了を実行者宛メンションつきでslack通知するようにした
はじめに
こんにちは。
SKIYAKIのエンジニアの家(@ie_webengineer)です。
今回やったこと
- slackのincoming-webhookを使えるようにする
- jenkinsデプロイ完了後に実行するjobの作成
- jenkinsユーザー名をslackのメンバーIDに変換する
- 変換したメンバーIDを元にメンションつきデプロイ完了メッセージをincoming-webhookでslackへ投稿する
やろうと思ったきっかけ
デプロイする際、jenkinsを使っているのですが、デプロイ完了後自分宛に通知がないと
他作業を途中始めてしまった時にデプロイが完了したことにすぐ気づけない問題がありました。
元々別のプロダクトで今回やったことを他のエンジニアが作ってたこともあり、
Bitfanではそれができていなかったため、勉強がてら自分でやってみました。
※コードをパクって実装してませんw
また、jenkinsにはslack通知するためのプラグインがありますが、
それはjob実行者への通知は少々難しい部分があったためシェルスクリプトで実現した経緯になります。
もちろん何のjobが完了したかはプラグイン使う方が楽なので合わせ技にしました。
・jenkinsのslack通知のプラグイン
今回ハマってしまったこと
jenkinsで実行した後、GAS(Google Apps Script)に通知内容を渡してやれば
多少メンテがしやすくコードも書きやすく簡単だと思って取り掛かったのですが、
外部からGASを実行する場合、アクセストークンが必要で
有効期限が無制限にはできないためjenkinsのjobから実行すると数分経つと、
有効期限切れで401エラーになってしまいました。
また、実行可能APIを選択して作ることもできますが、有料になってしまいそうだったため諦めました。
・参考情報
実装内容
slackのincoming-webhookを使えるようにする
以下記事の新方式で実施すれば簡単にできます。
jenkinsユーザー名をslackのメンバーIDに変換する
これが一番悩みどころだったのですが、以下の案が良いかなと考えました。
①jenkinsユーザーのメールアドレスからslackユーザー情報を取得する
②デプロイした最新コミット情報から取得したコミッターメールアドレスからslackユーザー情報を取得する
③slackのユーザーグループ情報からメンバーIDを抜き出し、ベタ書きでjenkinsユーザー名をslackメンバーIDに置き換える
①か②が良かったのですが、無理に頑張る必要もないので
①はjenkinsユーザーのメールアドレスを取得するには管理者権限が必要っぽかったので(自分が管理者ならできそう)諦めました...w
②は純粋にできそうだしテックブログネタ的ではありますが、jenkinsユーザー名だけで事足りそうだったためやめました。
結果的に③で対応しました。
jenkinsユーザー名から変換したメンバーIDを元にメンションつきデプロイ完了メッセージをslackへ投稿する
slackのメンバーID変換は他jobでも利用することになるので共通処理化するためにファイルに閉じた方が良いです。
jenkinsUserId="jenkinsのユーザーID"
apiToken="jenkinsのAPIトークン"
jobUrl="jenkinsのjobのurl"
curl -X GET --user $jenkinsUserId:$apiToken $jobUrl/api/json > jobs.json
url=$(cat jobs.json | jq -r ".builds[0].url")
curl -X GET --user $jenkinsUserId:$apiToken "${url}api/json" > detail.json
# job実行履歴情報からjenkinsのユーザー名取得
userName=$(cat detail.json | jq -r ".actions[0].causes[0].userName")
# jenkinsユーザー名をslackのメンバーIDに変換
case "$userName" in
"skiyaki-user-name1")
slackMemberId="メンバーID1"
;;
"skiyaki-user-name2")
slackMemberId="メンバーID2"
;;
esac
変換したメンバーIDを元にメンションつきデプロイ完了メッセージをincoming-webhookでslackへ投稿する
repositoryNameやenvなどはjobはごとに変えていけば良いのでベタ書きにしました。
repositoryName="bitfan_account"
env="staging"
message="<@$slackMemberId>\n$repositoryName $env へのデプロイが完了しました。"
# Slackメッセージを送信
curl -X POST -H 'Content-type: application/json' --data "{ 'text':'$message' }" https://hooks.slack.com/services/**************
結果
最後にデプロイを実行をしたユーザー宛にメンション通知することができました。
まとめ
地味に助かる運用改善が自分には結構楽しい分野だったりするため
身近な作業でこうなれば良いのにとかがあったら都度対応していきたいと思います。
株式会社SKIYAKIのテックブログです。ファンクラブプラットフォームBitfanの開発・運用にまつわる知見や調べたことなどを発信します。主な技術スタックは Ruby on Rails / React / AWS / Swift / Kotlin などです。 recruit.skiyaki.com/
Discussion