2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GraphQLAdvent Calendar 2022

Day 22

Mac版VBAからGitHub GraphQLを呼び出す

Last updated at Posted at 2022-12-17

概要

社内の自チームにて「みんなのソースレビュー完了時間が遅いかも?!」という感覚的な問題があがったので、
Mac版VBA × AppleScript × GitHub GraphQLを用いてGitHubからPR情報を取得し、自チームのレビュー生産性を数値化してみました。

Mac版VBAは情報が少ない上にActiveXが使えないのでPythonとかで作った方が効率的かなと思いましたが、
社内のプレゼンでもバエるようにExcelでグラフとかサマリーとか色々カスタマイズしたくなったのでこんな組み合わせになりました。

しかし、肝心のコードについては情報があまりなく試行錯誤したのでメモします。

構成

image_6483441.JPG

  • 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

VBA
' 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の設定

  • 引数gitHubTokenに以下の設定を行ったPersonal access tokenを渡している
    image_6483442.JPG

②AppleScriptからGitHub GraphQLへPOSTリクエスト

curl_github_graphql.scpt
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関数を再呼出

実行結果

で、最終的にVBAや数式でPR情報をごにょごにょしてサマリーした結果
image_6483443.JPG

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?