Open3

(github cli & jq)PRの作成からマージによるクローズまでが指定の日数におさまるPRを取得するスクリプト

ピン留めされたアイテム
ふじしろふじしろ

完成したスクリプト

#!/bin/zsh
# 前提: github cliのログインはすませておく

# GitHubのリポジトリ設定
owner="owner-name"
repo="target-repository-name"

# 1日を秒数に変換
one_day_seconds=$((24 * 60 * 60))

# 指定期間(日数)
days=1

gh api graphql --paginate -f query='
{
    repository(owner: "'${owner}'", name: "'${repo}'") {
        # 検索対象のPRはあらかじめマージ済みのものに絞っておく
        pullRequests(first: 100, orderBy: {field: CREATED_AT, direction: ASC}, states: MERGED) {
            nodes {
                ... on PullRequest {
                    number
                    title
                    url
                    createdAt
                    mergedAt
                    state
                }
            }
        }
    }
}
' |
jq -r  '.data[].pullRequests[].[] | [.number, .state, .url, .createdAt, .mergedAt, .title] | @tsv' |

# titleにはスペースが入っていることがあるので、一番最後にしてreadで読む
while IFS='	' read number state url createdAt mergedAt title; do
    # null回避
    [ $mergedAt = "null" ] && mergedAt=$(date -u +%Y-%m-%dT%H:%M:%SZ)

    mergedAt=$(echo -n $mergedAt | tr -d "'")
    createdAt=$(echo -n $createdAt | tr -d "'")
    leadDays=$(( $(( $(date -u -jf %FT%TZ  ${mergedAt} +%s) - $(date -u -jf %FT%TZ  ${createdAt} +%s) )) / $one_day_seconds ))
    createdAtJST=$(date -jf %FT%TZ  ${createdAt} +%FT%T%z)
    mergedAtJST=$(date -jf %FT%TZ  ${mergedAt} +%FT%T%z)

    # 期間に一致しない場合はスキップ
    [ $leadDays -ne $days ] && continue
    
    # PR番号 ステータス 作成日時 マージ日時 リードタイム タイトル URL
    echo $number $state $createdAtJST $mergedAtJST $leadDays $title $url
done 
ふじしろふじしろ

動機

タスクの相対見積もりのベースラインにするため、作成からマージまでの期間(リードタイム)が指定の日数に一致するPRを探していた。
スクリプト組めば簡単に取得できるのではと思った。

最初は簡単にいけるかと思ったが通常のghコマンドだと難しく、GraphQLを使う事になった。

めちゃくちゃ参考にさせてもらった記事(この記事のコードを元に試行錯誤)
https://zenn.dev/jnuank/articles/f8d6599073a2ef

github cliでgraphqlを使って検索するための動作確認に活用
https://docs.github.com/ja/graphql/overview/explorer

jqの使い方
https://www.tohoho-web.com/ex/jq.html#about

感想

すごくやってよかったと感じる。
目的の達成はもちろん、触れたことのなかったGraphQLの世界に触れることができていい経験になった。