これは何?
こちらはGitHub Advent Calendar 2024 4日目の記事です!
運用保守の中で、プロダクトマネージャー側から
〇〇ブランチに入った対応って、今JIRAに上がってるので全部かな?もし漏れてるのあったらチケットに起こしといて欲しい
という、ちょっとめんどくさい依頼がありました。
その際、以下のことが必要そうでした。
- 特定のブランチに入ったPull Requestたちを、タイトル/ID/マージ時刻/contributer含めてガバッと一覧化する
- 一覧化した各PullRequestに対して、少し備忘的にメモを付け加える
- その上で、スプレッドシート上にのせて保存、共有できる(GitHub分かんない人にも共有したい)
GitHubのWebサイト上でも検索とかソートはできるのですが、それをいちいちブラウザからコピペしてLocalのExcelに書き写して一覧化してメモかいて、ていうのがめんどくせ〜〜となったので、試しにGitHubAPIで一覧化してみました。その時の備忘録です。
作ったもの
import csv
import json
import codecs
import requests
# GitHubのPersonal Access Token
GITHUB_TOKEN = 'hoge' ##自分のやつを入れる
# リポジトリのオーナー名とリポジトリ名
OWNER = "hogeOwner"
REPO = "HogeRepo"
# ベースブランチ名
BASE_BRANCH = 'HogeBranch'
# APIリクエストURL
API_URL = f'https://api.github.com/repos/{OWNER}/{REPO}/pulls?base={BASE_BRANCH}&state=closed&sort=updated&direction=desc'#&since=2024-01-01T00:00:00Z'
# APIリクエスト
headers = {
'Authorization': f'token {GITHUB_TOKEN}',
'Accept': 'application/vnd.github+json'
}
params = {
'base': BASE_BRANCH,
'state': 'closed',
'sort': 'updated',
'direction': 'desc',
'per_page': 100 # 最大100件まで取得可能
}
# 全てのページのデータを取得
all_pulls = []
page = 1
while True:
params['page'] = page
response = requests.get(API_URL, headers=headers, params=params)
response.raise_for_status()
pulls = response.json()
if not pulls:
break
all_pulls.extend(pulls)
page += 1
print(f'{len(all_pulls)}件のデータを取得しました。')
# マージ時刻がNULLでないPRのみを抽出
#️ 検索APIの仕様上、「マージ済み」か「クローズされただけ」かを絞り込みできなかったので、手元で絞り込んだ
filtered_pulls = [pr for pr in all_pulls if pr['merged_at'] is not None]
# マージ時刻でソートする
sorted_pulls = sorted(filtered_pulls, key=lambda pr: pr['merged_at'])
# Excelで見やすいようにshift_jisで出力するけど、文字化けが発生する場合は?hoge?に変換する
codecs.register_error('none', lambda e: ('?hoge?', e.end))
# CSVファイルに書き込む
count = 0
with open('prs_sjis_backend_11.csv', 'w', newline='', encoding='shift_jis', errors='none') as csvfile:
fieldnames = ['id', 'title', 'user', 'created_at', 'merged_at', 'state', 'html_url']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for pr in sorted_pulls:
count += 1
writer.writerow({
'id': pr['id'],
'title': pr['title'],
'user': pr['user']['login'],
'created_at': pr['created_at'],
'merged_at': pr['merged_at'],
'state': pr['state'],
'html_url': pr['html_url']
})
print(f'{count}件のデータをCSV出力しました。')
ポイント
- 「マージされているかどうか」はgitHubAPIくんは直接教えてくれない。[merged_at]がNULLかどうかで判断するしかない。
備忘
GitHubのアクセス発行のやり方
使ったGitHubAPI ドキュメント
使ってみての所感
- トークン発行したら2秒で動いてくれたので嬉しい。楽。あとはスプシなり何なりに貼り付けるだけでOK。
- PythonScriptは ChatGPTくんに書かせたので楽だった(サボった)
追記
セマンティックバージョニング + GitHubのAutomatically generated release notes 使えば、似たようなことがタグの差分としてパッと出せることに気づいた。