経緯
会社のソースコード管理にGithubを使い開発を行なっていると、プルリクエストを作成してレビューを依頼する という流れがよくあると思います。
しかし、土日を跨いでしまったり、普段使わないリポジトリでのPRを出した際などに
うっかりレビューすることを忘れられてしまい、放置されるという事がまぁよくあります。
その度に毎回「レビューお願いします!」というコミュニケーションをとる必要が出てしまい、
正直無駄なコミュニケーションだなと思ったので
Graffityではレビュー待ちのPRをリポジトリ単位で通知するBotを作ってSlackで運用しています
こんな感じで毎朝(11時始業なので11時は朝です)各リポジトリのアクティブなPRの個数を通知してくれます。
全部マージ済み or ドラフトPRしかない場合はこんな感じで誉めてくれます。
このBotの実装について今回は紹介します。
技術選定
言語:Python3 (Pythonを使用している理由は会社での共通言語的な使い方をしているからです)
ライブラリ: PyGithub 1.55(実装時) https://github.com/PyGithub/PyGithub
Slackへの投稿はみんな大好きIncomingWebHookを使用
事前準備
まずはPyGithubを使うためにGithubのPersonalAccessTokenを取得する必要があります。
https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
会社で使う場合は会社のGithubアカウント的なアカウントで作るのが良いでしょう。
管理しやすい名前と期限を設定しておきましょう。
念の為無期限はやめといたほうが良いかなと。
権限に関しては今回はアクティブなPRの個数が知りたいだけなのでrepoにチェックを入れておきましょう。
生成ボタンを押すとトークンが表示されます。
これはページを離れると二度と見れなくなるのでメモしておきましょう(1敗
続いて、SlackでポストするためのIncomingWebhookのURLを発行しておきます。
マニュアルの手順に従い作成し、通知させたいSlackチャンネルも設定しておきましょう。
URLが作成されたらそれも控えておきます
https://slack.com/intl/ja-jp/help/articles/115005265063-Slack-%E3%81%A7%E3%81%AE-Incoming-Webhook-%E3%81%AE%E5%88%A9%E7%94%A8
最後にpythonで使用するライブラリをインストールしておきましょう
pip install PyGithub
実装
とりあえずコード全文です
import sys
from github import Github
import requests, json
WEB_HOOK_URL = "取得したWebhookURL"
# 監視対象リポジトリ
# ここに追加してね
TargetRepositories = ["https://github.com/HOGEHOGE/FUGAFUGA",
"https://github.com/HOGEHOGE/PIYOPIYO"]
def main():
args = sys.argv
if len(args) != 2:
print("引数がおかしいよ: github トークン入れてる?")
return -1
try:
github_instance = Github(args[1])
result_text = ["プルリクレビューの時間だよ!"]
for repo in github_instance.get_user().get_repos():
if repo.html_url in TargetRepositories:
active_pull_requests = [pr for pr in repo.get_pulls() if not pr.draft]
if len(active_pull_requests) > 0:
result_text.append(repo.html_url + " にアクティブなPRが" + str(len(active_pull_requests)) + "個あり:masu:")
output = "\n".join(result_text)
send_text = ''
if len(result_text) >= 2:
send_text = output
else:
send_text = "PR全部レビューしてるわ。偉い"
requests.post(WEB_HOOK_URL, data=json.dumps({
'text': send_text
}))
except Exception as e:
print("Error" + e)
return 1
return 0
statuscode = main()
sys.exit(statuscode)
使う際はこんな感じです
python main.py Githubのアクセストークン
各所解説
まずWebHookのURLと監視対象のリポジトリのリストを用意しています。
現状はコードにベタ書きにしています。(監視対象のリポジトリの増える頻度って新規プロジェクト発足時くらいなので)
WEB_HOOK_URL = "取得したWebhookURL"
# 監視対象リポジトリ
# ここに追加してね
TargetRepositories = ["https://github.com/HOGEHOGE/FUGAFUGA",
"https://github.com/HOGEHOGE/PIYOPIYO"]
ただし、GithubのアクセストークンはGit管理したくなかったので(それはそう)引数として受け取るようにしています
args = sys.argv
if len(args) != 2:
print("引数がおかしいよ: github トークン入れてる?")
return -1
PyGithubの初期化を行います。
引数にはアクセストークンを入れます
github_instance = Github(args[1])
ここが今回で一番キモとなる部分です。順を追って説明します
for repo in github_instance.get_user().get_repos():
if repo.html_url in TargetRepositories:
active_pull_requests = [pr for pr in repo.get_pulls() if not pr.draft]
if len(active_pull_requests) > 0:
result_text.append(repo.html_url + " にアクティブなPRが" + str(len(active_pull_requests)) + "個あり:masu:")
まずgithub_intance.get_user()で自分自身の情報を取得します。
そこからさらにget_reposをすることで「自分が見ることのできるリポジトリの一覧」を取得できます(ここで言う”自分”とはアクセストークンを発行したユーザーです)
それをforで回すことで、自分が見れるリポジトリを全てチェックしていく事ができます
for repo in github_instance.get_user().get_repos():
repoの中にhtml_urlというのがあるので、前述のTargetRepositoriesと一致している場合のみ処理を続行します
if repo.html_url in TargetRepositories:
get_pullsでPullRequestの情報が取得できます。
その中からdraftじゃないものを抽出し。1個以上あった場合は通知対象としてテキストをリストに追加します
active_pull_requests = [pr for pr in repo.get_pulls() if not pr.draft]
if len(active_pull_requests) > 0:
result_text.append(repo.html_url + " にアクティブなPRが" + str(len(active_pull_requests)) + "個あり:masu:")
最後に、配列の長さでPRがあるかをチェックし、ない場合は誉めてあげるテキストを入れた上でWebhookURLに対してPostを行えば完了です
output = "\n".join(result_text)
send_text = ''
if len(result_text) >= 2:
send_text = output
else:
send_text = "PR全部レビューしてるわ。偉い"
requests.post(WEB_HOOK_URL, data=json.dumps({'text': send_text}))
運用してみて
実装自体は1時間もかからずにできたBotなのですが大変便利です。
レビュー漏れが無くなるしいちいち「レビューお願いします!」といったコミュニケーションもしなくて済むので快適です。
Graffityではこのpythonコードをビルドマシンのcronで平日朝に定期実行しています。
朝にレビューBotの投稿を見てそこからレビューするというルーチンにもなっており、レビュー促進もされており良い感じです。
ぜひ興味があれば導入を検討してみてください〜