Node.js
Octokit

NodeJSからGitHub経由でブランチの作成、コミット、プルリクの作成をする

自動化できないかなと思って少し調べたのでメモ


やりたいこと


  • branchの作成

  • ファイルの更新・コミット

  • pull-reqの作成


NodeJSからGitHubを叩く

@octokit/restのライブラリを使う。

GitHubのREST APIのNode IF。

node-githubから移行されたとのこと。


ドキュメント

以下にAPIのドキュメントがある。

https://octokit.github.io/rest.js/

――が、実際はGitHub APIのラッパーなので、そちらと見比べながらやるのがいい。


debugモード


Set DEBUG=octokit:rest* for additional debug logs.


環境変数にセットすれば行けるらしい。


やってみる


初期化

import Octokit from '@octokit/rest'

const octokit = new Octokit()

Enterprise環境とかだと設定が必要だったりするけど、叩くのはEnterpriseじゃないので設定しない。


認証

プライベートリポジトリや一部APIを叩くには認証が必要。

ocktokitにはいくつか認証方法が提供されているけど、今回はAccessTokenが手元にある前提で行う。

AccessTokenは本家で発行する、またはOAuthして取ってくる必要がある。

※例えばこう koa+passportでGitHub認証

AccessTokenがあるなら authenticate を叩くだけ。

octokit.authenticate({

type: 'token',
token: accessToken,
})

返り値などは特にない。

参考: https://github.com/octokit/rest.js#authentication


referenceの取得

つまりブランチ。作成したいブランチの元となるブランチの情報をとってくる。

const origin = await octokit.gitdata.getReference({

owner: 'rymizuki',
repo: 'example',
ref: 'heads/master',
})

あくまでここで扱うのはreferenceなので、heads/ブランチ名になる。

参考: https://octokit.github.io/rest.js/#api-Gitdata-getReference


referenceの作成

取得したreferenseから新しくreferenseを切る。

const ref = await octokit.gitdata.createReference({

owner,
repo,
ref: 'refs/heads/test',
sha: origin.data.object.sha,
})

元ブランチのshaから派生させる。

refには「refsから始まり/を2つ以上含む」という制約がある。

なお、同名のreferenceを作成しようとするとエラーになる。

参考: https://octokit.github.io/rest.js/#api-Gitdata-createReference


ファイルの取得

今回の要求としては「すでに存在しているファイルを上書き更新」なので、ファイルを取得する。

const content = await octokit.repos.getContent({

owner,
repo,
ref: 'heads/test', // さっき作ったブランチの情報をとってくる
path: 'README.md', // ファイルパス
})

// とってきたデータをデコードする
const data = new Buffer(content.data.content, content.data.encoding).toString()

参考: https://octokit.github.io/rest.js/#api-Repos-getContent


ファイルの更新

コミットしてプッシュする。

以下のAPIを叩くことで、ファイルの送信、commitの作成をGitHub上で行うことができる。

const updateResult = await octokit.repos.updateFile({

owner,
repo,
branch: 'test', // これはreferenceではなくbranch
message: 'docs(README): なんやかんや', // コミットメッセージ
path: 'README.md',
content: new Buffer(`${ data }\n\n更新したよ`).toString('base64'), // base64にエンコードする
sha: content.data.sha,
})

参考: https://octokit.github.io/rest.js/#api-Repos-updateFile


PullRequestの作成

const pullreq = await octokit.pullRequests.create({

owner,
repo,
head: 'test', // マージしたいブランチ
base: 'master', // マージされたいブランチ
title: 'README.mdを更新した', // pull-reqのタイトル
body: 'ほにゃらら', // pull-reqの本文
})

参考: https://octokit.github.io/rest.js/#api-PullRequests-create


まとめ


  • ブランチの作成からPullReqの作成までの流れを紹介しました

  • authenticateはaccessToken使っとくのが一番わかり易い

  • refarenceとheadとbranchの関係を理解して使おう

  • GitHub APIはとっても多機能だけど、使いこなせると便利そうですね