GitHub API v3を使ってPull Requestから変更差分のあるファイルの一覧とファイル内容を取得する

2020.10.05

こんにちは、CX事業本部の若槻です。

GitHubでは現在REST APIとしてGitHub API v3を使用することが可能です。

今回は、GitHub API v3を使ってPull Requestから変更差分のあるファイルの一覧とファイルの内容の取得をShell(curl)によりしてみました。

やってみた

アクセストークンの発行

まず、GitHub APIアクセス時の認証に使用するOAuth2アクセストークンを発行します。

https://github.com/settings/tokens/new にアクセスしてアクセストークンの新規発行ページを開きます。

[Note]でトークン名(または用途)を入力して、[Select scopes]でrepoにチェックを入れます。(repoではなく、その配下のスコープのみチェックした場合は「List pull requests」の時点でアクセスができませんでした) image

同じページ下部の[Generate token]をクリックします。 image

アクセストークンが新規発行されました。トークン値が表示されるので控えておきます。 image

GitHub APIアクセス時のお決まり

APIを実際に叩く前に、GitHub APIアクセス時のお決まりについて確認します。

各種APIアクセス時にアカウント固有で共通で必要となる情報は以下となります。これらは変数で予め指定しておきます。

% TOKEN=<先ほど控えたアクセストークン値>
% REPOSITORY=<取得するPull RequestがあるRepository名>
% OWNER=<RepositoryのOwnerアカウント名>

また、APIホストはhttps://api.github.comとなります。

APIアクセス時にはAcceptヘッダーを次のように指定して利用するAPIバージョンを明示的に指定することが推奨されています。

"Accept: application/vnd.github.v3+json"

認証が必要なGitHub APIへのアクセス時にはAuthorizationヘッダーを次のように指定して認証を行います。

"Authorization: token OAUTH-TOKEN"

詳細については次のドキュメントを参照ください。

Pull Requestの取得

ここから実際にAPIを叩いていきます。

まず、変更差分を取得したいPull Requestを取得します。Pull Requestの取得方法には次の2つがありますが、

今回は「List pull requests」により直近で更新されたopen状態のPull Requestを取得してみます。「List pull requests」のメソッドおよびエンドポイントは以下となります。

GET /repos/{owner}/{repo}/pulls

また今回は「List pull requests」で使用可能な以下のParameterを指定します。

  • stateopen(Pull Requestの状態をopen, closeまたはallで指定できる)
  • sortupdatedcreated, updated, popularity または long-runningで指定できる)
  • directiondesc(ソート方向を指定できる。既定はasc。)

curlでAPIにアクセスしてPull Request一覧を取得してみます。取得結果は変数pullsに格納します。

% pulls=$(curl \
  -H "Accept: application/vnd.github.v3+json" \
  -H "Authorization: token ${TOKEN}" \
  "https://api.github.com/repos/${OWNER}/${REPOSITORY}/pulls?state=open&sort=updated&direction=desc")

ここで取得したい情報は直近に更新されたPull Requestの番号です。pullsからjqで取得して変数pull_numberに格納します。今回は16となります。

% pull_number=$(echo $pulls | jq '.[0].number')
% echo $pull_number
16

Pull Requestから変更差分のあるファイル一覧を取得

次に先ほど取得したPull Requestの番号を元に、Pull Requestから変更差分のあるファイル一覧を取得します。その場合は「List pull requests files」を使用します。

「List pull requests files」のメソッドおよびエンドポイントは以下となります。

GET /repos/{owner}/{repo}/pulls/{pull_number}/files

curlでAPIにアクセスしてPull Requestから変更差分のあるファイルのファイル一覧を取得してみます。ただしここでは後続の処理で使うためコンテンツURL(contents_urlを取得します。このコンテンツURLの文字列内にファイルの情報も含まれています。また先ほどと違い変数を介すとURLエンコードが必要な文字が含まれている場合にデコードが面倒なので直接jqに流し込んでコンテンツURLのリストを変数contents_urlsに格納します。

% contents_urls=$(curl \
  -H "Accept: application/vnd.github.v3+json" \
  -H "Authorization: token ${TOKEN}" \
  "https://api.github.com/repos/${OWNER}/${REPOSITORY}/pulls/${pull_number}/files" | \
jq '[.[].contents_url]')

取得できたコンテンツURLは以下となります。

% echo $contents_urls
[
  "https://api.github.com/repos/<オーナー名>/<リポジトリ名>/contents/dir1/article.md?ref=301c68a9ebad2c591bdfd0b124f8e4d73175a96a",
  "https://api.github.com/repos/<オーナー名>/<リポジトリ名>/contents/dir1/dir2/config.json?ref=301c68a9ebad2c591bdfd0b124f8e4d73175a96a"
]

今回はPull Requestでdir1/article.mdおよびdir1/dir2/config.jsonの2ファイルに差分が発生していることが分かります。またここでrefに指定されている値はPull RequestのHEADの参照を表しています。

変更差分のあるファイルの内容を取得

次に先ほど取得したコンテンツURLを使用して、Pull Requestで変更されたファイルの内容を取得します。

コンテンツURLにアクセスした際のレスポンスでは、ファイルの内容はcontentにBase64暗号化されて指定されるので復号する必要があります。1つ目のコンテンツURLから復号した内容を取得してみます。

% contents_url=$(echo $contents_urls | jq -r '.[0]')
% curl \
  -H "Accept: application/vnd.github.v3+json" \
  -H "Authorization: token ${TOKEN}" \
  "${contents_url}" | jq -r '.content' | base64 -d

こんにちは、CX事業本部の若槻です。

今回は、GitHub APIを使ってPull Requestから変更差分のあるファイル一覧を取得してみました。

こんにちはから始まるファイル内容を取得することができました。

おわりに

GitHub API v3を使ってPull Requestから変更差分のあるファイルの一覧とファイルの内容を取得してみました。

今回確認したGitHub APIを使用して作成したいChrome拡張があったのでこれで何とか作れそうです。作れ次第共有したいと思います。

参考

以上