使用graphql-client gem来访问Github API v4
代码
在特定的代码仓库中获取特定成员在特定日期之后被合并的PR清单。
source 'https://rubygems.org'
gem 'graphql-client' # 0.12.1
#! /usr/bin/env ruby
require 'graphql/client'
require 'graphql/client/http'
h = GraphQL::Client::HTTP.new('https://api.github.com/graphql') do
def headers(context)
{
"Authorization" => "Bearer #{ENV['ACCESS_TOKEN']}"
}
end
end
s = GraphQL::Client.load_schema(h)
c = GraphQL::Client.new(schema: s, execute: h)
Q = c.parse <<-GraphQL
query($after: String) {
repository(owner:"our_company", name:"awesome_project") {
pullRequests(first: 100, states: [MERGED], orderBy: {field: UPDATED_AT, direction: DESC}, after: $after) {
edges {
cursor
node {
number
title
updatedAt
mergedAt
author {
login
}
}
}
}
}
}
GraphQL
all_nodes = []
after = nil
loop do
r = c.query(Q, variables: { after: after })
nodes = r.data.repository.pull_requests.edges.map(&:node)
nodes_in_time = nodes.select { |n| Time.parse(n.updated_at) > Time.new(2017, 10, 30) }
all_nodes += nodes_in_time.select { |n| %w(alice bob carol).include?(n.author.login) }
break if nodes.size > nodes_in_time.size
after = r.data.repository.pull_requests.edges.last.cursor
end
puts all_nodes.map { |n| "##{n.number}\t#{n.author.login}\t#{n.merged_at}\t#{n.title}" }
多样的解释
-
- アクセストークンはPersonal access tokensのページで作れる
-
- Qが定数なのはgraphql-clientの仕様で、queryメソッドに引数で渡すクエリ文字列が定数で無かった場合はエラーになる
-
- orderByに何を指定したら良いかはドキュメントにはほとんど書かれていないがExplorerで適当に打つと補完されるのでわかる
-
- 1回の取得件数が100件までなので、複数回に分けて取得する必要がある
-
- edgeとnodeとcursorの仕組みはgraphQLではスタンダードとのこと
cursorを指定してここ以降を取得、とやることでデータを取得していく
結果のオブジェクトはHashieよろしくメソッドで項目にアクセスできるが、元がmergedAtのようにcamelCaseであるものはmerge_atのようにsnake_caseのメソッド名になる