LoginSignup
17
10

More than 5 years have passed since last update.

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

Posted at

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

やりたいこと

  • 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はとっても多機能だけど、使いこなせると便利そうですね
17
10
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
17
10