概要
octokit.rbとは、GitHub API v3に対応したRubyのクライアントである。リポジトリのREADMEを見てもわからなかった部分が多いので、メモ
リポジトリの場所
github:octokit/octokit.rb
基本的な使い方
アカウント設定
username/passwordでログイン
usernameとpasswordを記述するシンプルな例です。
client = Octokit::Client.new login: "USER_NAME", password: "PASSWORD"
client.user # GitHub上のユーザー情報を取得
2段階認証を有効にしている場合
GitHubのログインに2段階認証を有効にしている場合、下記のようにリクエストヘッダーを追加しなければなりません。
client = Octokit::Client.new login: "USER_NAME", password: "PASSWORD"
user = client.user("defunkt", :headers => { "X-GitHub-OTP" => "<your 2FA token>" }) # GitHub上のユーザー情報を取得
毎回リクエストする度にX-GitHub-OTPをヘッダーに追加しなければならないので、下記のようにOAuth tokenを発行すると良いです。
client = Octokit::Client.new login: "USER_NAME", password: "PASSWORD"
token = client.create_authorization(:scopes => ["user"], :headers => { "X-GitHub-OTP" => "<your 2FA token>", :note => "<name of token>" })
# => <your new oauth token>
note
には任意の名前を指定します。ここで発行されたトークンは、Personal access tokensに反映されます。
oauth tokenでログインする
発行したOAuth Tokenは下記のようにクライアントで利用します。
client = Octokit::Client.new access_token: token
僕はaccess_tokenというキー名を忘れがちです。何かいい方法があれば良いのですが…。
.netrcにusername/passwordを書く
まず~/.netrcに下記のように書きます。
machine api.github.com
login USER_NAME
password PASSWORD
PASSWORDにはOAuth Tokenを指定することもできます。
clientは下記のように作成します。
client = Octokit::Client.new netrc: true
client.user # GitHub上のユーザー情報を取得
.netrcを利用する場合はnetrc gemが必要だそうです。(未確認)
GitHubから情報を取得する
developer.github.com に公開されているAPIと対になるメソッドがOctokit::Clientに定義されています。例えばIssueの取得であれば、
client = Octokit::Client.new
client.issues 'kompiro/hoge' # => kompiro/hogeリポジトリのissueを取得
と言った感じ。何も指定しないと、1ページ辺り50件で取得する。ページングをするには、後述するrelationの理解が必要。
このissuesメソッドはOctokit::Client::Issues
に定義されている。同様にRepositoryの操作であれば、Octokit::Client::Repositories
に定義されている。
取得したオブジェクトの属性にアクセスする
octokit.rbで取得したデータは、そのオブジェクトの属性であれば、直接アクセスできます。
user = client.user
user.login
# => "kompiro"
user.name
# => "Hiroki Kondo"
関連するオブジェクトを取得する
octokit.rbは、関連するオブジェクトの取得は属性「rels」を経由して取得します。これはoctokit.rbの内部で使っている「Sawyer」の特徴です。
例えば、ユーザーの所有するリポジトリの一覧を取得するには
repos_rel = client.user.rels[:repos]
repos_rel.href
# => ""https://api.github.com/users/USER_NAME/repos
repos_rel.get.data
# => ユーザーの所有しているリポジトリのデータを取得
ページングで前のページ/次のページの取得をするには?
例えば取得したIssuesの次のページを取得するには、下記のようにアクセスします。
issues = client.issues 'kompiro/hoge'
next_page = client.last_response.rels[:next].get.data
全てのページを取得するには、
last_response = client.last_response
while last_response.rels[:next]
last_response = last_response.rels[:next].get
issues.concat last_response.data
end
というようにすれば取得できるけど、client.auto_paginate = true
とすると、全てのページを走査して単一の配列にします。
その他
ユーザーアイコンを表示するには?
GitHubに表示されているユーザーアイコンは、Gravatarに登録したアイコンが表示されているはずです。つまり、ユーザーアイコンを表示するには、Gravatarにアクセスするのが手っ取り早いです。
GravatarのIDはclient.user.gravatar_idで取得できます。
client.user.gravatar_id
# => "e7bf914803991968f32535ff47cee5d2"
これは、Gravatarの画像用のハッシュなので、そのまま下記のようにURLを作るメソッドがあると、Gravatarに登録されたアイコンを取得できるURLがわかる。helperにしておくと便利。
def gravatar_url gravatar_id
"http://www.gravatar.com/avatar/#{gravatar_id}"
end
GitHub GraphQL にアクセスする(2018/03/25 加筆)
graphql-client
という gem もあってschemaのチェックとかしてくれるけど、基本 GraphQL Explorer を使ってクエリは作ると思う。octokitでやっちゃいましょ
require 'octokit'
require 'json'
client = Octokit::Client.new(access_token: ENV.fetch('GITHUB_TOKEN'))
query = <<GRAPHQL
query($owner: String!, $repo: String!) {
repository (owner: $owner, name: $repo){
pullRequests(
first: 100,
states: MERGED) {
nodes {
number
title
mergeCommit {
oid
}
author {
login
}
mergedAt
participants(first: 100) {
nodes {
login
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}
}
GRAPHQL
variables = { owner: 'kompiro', repo: 'pr-summary' }
param = {query: query, variables: variables}.to_json
result = client.post '/graphql', param