概要
社内の自チームにて「みんなのソースレビュー完了時間が遅いかも?!」という感覚的な問題があがったので、
Mac版VBA × AppleScript × GitHub GraphQL
を用いてGitHubからPR情報を取得し、自チームのレビュー生産性を数値化してみました。
Mac版VBA
は情報が少ない上にActiveXが使えないのでPython
とかで作った方が効率的かなと思いましたが、
社内のプレゼンでもバエるようにExcelでグラフとかサマリーとか色々カスタマイズしたくなったのでこんな組み合わせになりました。
しかし、肝心のコードについては情報があまりなく試行錯誤したのでメモします。
構成
- Mac版VBA:Excel
- Excelシートの入力値を取得する
- AppleScriptを呼び出してPR情報(JSON)を取得する
- PR情報をパースして集計し、Excelシートに出力する
- AppleScript:通信
- VBAから受け取った検索パラメータをGitHub GraphQLにPOSTリクエストする
- レスポンス結果のPR情報(JSON)をVBAに返却する
- GitHub GraphQL:外部API
- POSTリクエストの検索パラメータに従ってPR情報(JSON)がレスポンスされる
呼出方法
①Mac版VBAからAppleScript
' GitHubから指定アカウントIDに関連するPRのJSONデータを取得する
Function FetchGitHubJson(gitHubToken As String, gitHubId As String, createdFrom As String, createdTo As String, endCursor As String) As String
Dim params As String: params = gitHubToken & "," & gitHubId & "," & createdFrom & "," & createdTo & "," & endCursor
FetchGitHubJson = AppleScriptTask("curl_github_graphql.scpt", "postGithubGraphqlJson", params)
End Function
-
AppleScriptTask
で下記ローカルディレクトリに用意したcurl_github_graphql.scpt
ファイルのpostGithubGraphqlJson
関数を呼び出す~/Library/Application Scripts/com.microsoft.Excel/curl_github_graphql.scpt
-
AppleScriptTask
は固定引数のため、複数の検索パラメータをカンマ区切りの文字列にして第三引数params
に渡している
Personal access tokenの設定
②AppleScriptからGitHub GraphQLへPOSTリクエスト
use scripting additions
use framework "Foundation"
on postGithubGraphqlJson(params)
set paramList to params
set OriginalDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set paramList to text items of paramList
set AppleScript's text item delimiters to OriginalDelimiters
set github_token to item 1 of paramList
set github_id to item 2 of paramList
set created_from to item 3 of paramList
set created_to to item 4 of paramList
set end_cursor to item 5 of paramList
set query to replaceString(getQL(github_id, created_from, created_to, end_cursor), "\\n", "")
do shell script "curl -H 'Authorization: bearer '" & github_token & " -X POST -d '{ \"query\":" & query & "}' https://api.github.com/graphql"
return result
end postGithubGraphqlJson
on getQL(github_id, created_from, created_to, end_cursor)
set with_cursor to ""
if end_cursor is not "" then
set with_cursor to ", after: \\\"" & end_cursor & "\\\""
end if
set query to " \"
{
search(type: ISSUE, first: 100, query: \\\"is:pr is:closed involves:" & github_id & " created:" & created_from & ".." & created_to & " NOT 集約 NOT Revert in:title comments:>=1 sort:created-asc\\\"" & with_cursor & ") {
edges {
node {
... on PullRequest {
author {
login
}
title
url
changedFiles
additions
deletions
createdAt
mergedAt
closedAt
comments(first: 50) {
edges {
node {
author {
login
}
createdAt
}
}
}
reviews(first: 50) {
edges {
node {
author {
login
}
createdAt
}
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
\" "
return query
end getQL
on replaceString(originalStr as text, pattern as text, newString as text)
set regularExpression to current application's NSRegularExpression's regularExpressionWithPattern:pattern options:0 |error|:(missing value)
return (regularExpression's stringByReplacingMatchesInString:originalStr options:0 range:{location:0, |length|:count originalStr} withTemplate:newString) as text
end replaceString
- VBAから直接呼ばれる関数は
postGithubGraphqlJson
- カンマ区切りの文字列で送信されてきたパラメータをリストに変換し、1要素ずつ取り出している
-
curl
を実行してGitHub GraphQLにPOSTリクエストし、レスポンス結果を返却している
GitHub GraphQLについて
クエリを確認する方法
前述のcurl_github_graphql.scpt
のようにクエリを利用し、GitHubで管理されているリポジトリ情報やユーザー情報などを取得することができます。
しかし、クエリの種類は多岐にわたるので、お手軽に確認したい場合はGitHubのWebアプリ「GraphQL API Explorer」を利用することをオススメします。
ただ、これ自体がGitHubのOAuthアプリになっており、Privateリポジトリに対してクエリを実行したい場合はOrganizationの承認が必要です。
注意点
- クエリをGitHub GraphQLへリクエストする際、改行コードがあればブランクに変換しないといけない
-
GitHub GraphQLの仕様により、リクエスト1回につきレスポンスデータは100件まで
- 対応として、VBA側で以下の処理を行っている
- 101件以上のデータが存在する場合(
pageInfo.hasNextPage
がtrue)、
100件目のカーソル(pageInfo.endCursor
)を引数にしてFetchGitHubJson
関数を再呼出
- 101件以上のデータが存在する場合(
- 対応として、VBA側で以下の処理を行っている