死んだブランチをslackに通知するツールを作った
ブランチ同士で依存が複雑な開発を乗り越えた後ってブランチの消し忘れが案外多かったりしますよね。しかも、消し忘れたとしても実害はない上に、消そうと思えばすぐに消せることも相まって後回しにしてしまうことも多いです。(自分はそう)
しかし、消し忘れたブランチが積もるとCUIだろうがGUIだろうがブランチを探す時に見づらくなります。また、似たような名前の開発ブランチを不用意に消してしまうリスクをわざわざ抱えておく必要は全くありません。
そこで、開発が停止した死んだブランチをslackに通知するツールを作りました。
実装
複雑なことはしていません。Gitのコマンドを叩いて整形した結果をslackに送っているだけです。
1.gitのコマンドを叩く
長く放置されているブランチを探す必要があったので、リモートブランチを全て取得し、そのブランチひとつひとつについて最終コミットを見ていくことにしました。
コマンドの叩いている下の処理では改行で分割したり空白を削除したりHEADブランチを除いたりしています。これでブランチの配列を得られました。
続いて、取得したブランチ名を使ってコミットログを確認します。
ログのフォーマットを指定してJSON形式にしています。lexerを作ってtoken列を作り、それをパースしているものを見かけましたが、さすがに面倒くさいですしGo製のgitのライブラリを作っているわけではないので、いじりやすいJSONで良しとしました。
2.logの整形を行う
JSON形式で吐き出させたログをdecodeした後、最終コミッターをkeyとしたmapに構造を作り変えました。こうしておくと通知した際に当事者意識が湧くのでは?という意図からです。GitHubの表記とslackの表記が一致している場合はメンションをつけてしまうのもアリかもしれません。
また、今回の目的は「古いブランチを通知すること」なので、最終コミットが2週間より短い場合は通知対象から除外しました。
3.Slack通知用の形式にまとめる
slackへのメッセージの表示の仕様は下記のリンクに記載されています。
そのため、続いてはこのAttachmentにデータを変換します。変換とはいえ実装は単純なのでAttachmentの構造体の定義だけ示します。
※例は上記のリンク先にあるので、他の表示形式が見たい場合は飛んで確認してみてください
4.WebhookでSlackに通知する
あとはAttachmentをbodyに突っ込んでpostするだけです。
Attachment以外にもユーザー名やアイコンも変更することができます。
※リクエスト先はwebhookを有効にする時にslackが生成してくれるので、それを使います。
結果
最終コミットから2週間以上のブランチが列挙されています。
この一覧の上部には最終コミッターの名前が入るようになっています。
ちなみに、通知を流し見してしまう人のために、ブランチを古い順にソートしています。これで「◯◯日も放置されていたのか...。さすがに消さないとなぁ。」というお気持ちになってもらえれば嬉しいです。
まとめ
久々にGoを書いたので文法を忘れているところがいくつかありました。ただ、シンプルな言語なだけあって、思い出してしまえば手は簡単に動くのでそこまで悩まず作れました。
また、データ構造の整形時にGoroutineを使ってみたのですが、配列やMapに追加する際にロックを入れるせいなのか速くならなかったので断念しました。
※10,000件のログ(ブランチ)に対して処理を行っています
まだまだ課題として、突貫で作ったのでロジックや命名、責務の分け方は雑ですし、POST先のURLも現在は空文字です。(コミットしていないですがローカルでは値があります)
本当は2週間おきにGitHub Actionsで定期実行する予定でしたが、面倒くさくて取り掛かっていません。。。
このあたりは時間を作ってさっさと改善してしまいたいですね。
Golangっぽくない実装や改善できそうな箇所や拡張できそうな機能についてアイデアがありましたら、ぜひコメントorPRを出してもらえればと思います。