Github PR作成 from GAS

昔作ったけど、気に食わなかった&他社で作ったから勝手に使えないので自社用に作り直したぉ。
ごにょごにょしたらスプレッドシートから作れるね!

おもむろにこんなのを用意しましょう。
github_repos_api.gs

var GithubReposAPI = function(repositoryOwner, repository, accessToken) {
  this.repositoryOwner = repositoryOwner;
  this.repository = repository;
  this.accessToken = accessToken;
};
// PRとブランチをセットで作成
GithubReposAPI.prototype.createPullRequestWithBranch = function(sourceBranchName, newBranchName, authorName, authorEmail, title, body, draft) {
  this.createBranch(sourceBranchName, newBranchName, title, authorName, authorEmail);
  return this.createPullRequest(title, body, newBranchName, sourceBranchName, draft);
}

// ブランチ作成
GithubReposAPI.prototype.createBranch = function(sourceBranchName, newBranchName, message, authorName, authorEmail) {
  const commit = this.createCommit(sourceBranchName, message, authorName, authorEmail);
  return this.execute(
    'POST',
    '/git/refs',
    {
      'ref': 'refs/heads/' + newBranchName,
      'sha': commit.sha
    }
  );
};
GithubReposAPI.prototype.createCommit = function(branchName, message, authorName, authorEmail) {
  const branch = this.fetchBranch(branchName);
  return this.execute(
    'POST',
    '/git/commits',
    {
      'message': message,
      'author': {
        'name': authorName,
        'email': authorEmail
      },
      'parents': [
        branch.commit.sha
      ],
      'tree': branch.commit.commit.tree.sha
    });
};
GithubReposAPI.prototype.fetchBranch = function(branchName) {
  return this.execute('GET', '/branches/' + branchName);
};

// PR作成
GithubReposAPI.prototype.createPullRequest = function(title, body, head, base, draft) {
  return this.execute(
    'POST',
    '/pulls',
    {
      'title': title,
      'body': body,
      'head': head,
      'base': base,
      'draft': draft
    }
  );
};

GithubReposAPI.prototype.execute = function(method, api, payload) {
  const url = 'https://api.github.com/repos/' + this.repositoryOwner + '/' + this.repository + api;
  const param = this.generateParam(method, payload);
  return fetch(url, param);
};
GithubReposAPI.prototype.generateParam = function(method, payload) {
  if (payload) {
    return {
      'method': method,
      'Content-Type': 'application/json',
      'muteHttpExceptions': true,
      'payload': JSON.stringify(payload),
      'headers': {
        'Authorization': 'token ' + this.accessToken
      }
    };
  }
  return {
    'method': method,
    'Content-Type': 'application/json',
    'muteHttpExceptions': true,
    'headers': {
      'Authorization': 'token ' + this.accessToken
    }
  };
};

function fetch(url, param) {
  Logger.log('[Request]---------------------------\n' + url + '\n' + JSON.stringify(param));
  var ret = JSON.parse(UrlFetchApp.fetch(url, param));
  Logger.log('[Response]---------------------------\n' + JSON.stringify(ret));
  return ret;
}


使い方

const api = new GithubReposAPI(
  'arrvis', // organization or username
  'test-repository', // リポジトリ名
  'XXXXXXXX' // Personal Access Token
);
api.createPullRequestWithBranch(
  'master', // 元ブランチ
  'feature/hoge', // 新しく作るブランチ名
  'Yutaka Izumaru', // author名
  'y.izumaru@arrvis.com', // authorメアド,
  'PRタイトル',
  'PR本文',
  false // draftかどうか
);