GAS経由でGitHub IssueをGoogle Sheetへ自動更新【GoogleAppsScript】【GitHub】

プロジェクト管理をするときにいろいろ選択肢があるのかで,個人プロジェクトや同人チームだとGoogle スプレッドシートを使うことが多々あるかと思います. GitHubのissueと当時に使用するときに両方更新するのはめんどくさいので,issue側を使用してシートは確認用で自動的に更新されるようにしました (実際に所属しているチームで使用しています)

導入前のタスク管理方法と過去の状態

以下のチーム(二人や一人のところもあるのでチームとは呼べない部分もありますが,ここではチームをします)があります.

  • Unityでのゲーム実装
  • ゲームの企画と仕様
  • ゲームで使用するイラスト
  • 運営上のタスク

これらの全体のタスクを可視化して,進捗を確認するためにすべてをGoogle スプレッドシートで管理を行っていましたが,開発側はGitHubを使用しているためissueを使いタスクのcloseなどを自動化したいという要望がありました. そこでGitHubのissueをメインで使用して,スプレッドシートを確認用だけに変更する方針にしました.

Demo

実際のGooleスプレッドシート側の画像になります.ぼかしていますが,タスク名・タスク内容・担当・issueへのリンクを表示しています.

GitHubからissueの取得

GitHubのアクセストークンの取得方法

まずはGASからGitHubにアクセスしたいので,GitHubのアクセストークンを発行します.

  1. GitHubの右上のところからSettingsを開きます.

2 . サイドメニューの Deleloper settings を開きます.

3 . Personal sccess token から Generate new token で新規にトークンを作成します

生成時の設定は repo に入れてます. 名前は任意のものを入れて,日程は使用する期間を設定します.

実装内容

上記でアクセストークンを取得することができたため,以下のスクリプトで任意のRepositoryのissueを取得することができるようになります. issueのステータスは,以下の3つを指定できますので使用する状況に合わせて変更していきます

状態 パラメータ
全て取得 all
開いているもの open
閉じているもの closed

(以下のコードはopenで指定しています)

参考サイト(GitHubのissueのAPIドキュメント)

https://docs.github.com/en/rest/reference/issues

function GetOpenIssues() {
  var url = 'https://api.github.com/repos/GitHub Your Name/RepositoryName/issues?state=open&per_page=100';
  var accessToken = 'your accessToken';
  var headers = {
    'Authorization': 'token '+ accessToken
  };

  var options = {
    'method': 'GET',    // GETやPUTなどを指定します。Qiita APIによって異なります
    'headers': headers,  // 上で作成されたアクセストークンを含むヘッダ情報が入ります
  };
  var response = UrlFetchApp.fetch(url, options).getContentText();
  var data = JSON.parse(response);
  return data;
}

Googleスプレッドシートの更新

スプレッドシートのIDの取得

まず更新シートのIDを取得します.

実装内容

取得したスプレッドシートのIDからデータの更新を行っていきます. 先ほどGitHubのissueから一覧を取得したので,これらの一覧データを引数に入れてスプレッドシート内のデータを更新しています.

function UpdateGSheet(issueDataList) {
  var sheetId = 'your sheet id';
  var sheetName = 'クライアント';
  var ss = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);

  var issueObjectList = []
  var issueSize = Object.keys(issueDataList).length;
  console.log("issue size:" + issueSize);
  for(var index = 0;index < issueSize ;index++){
    var d = issueDataList[index];
    var issueObject = UpdateIssue(d);
    issueObjectList.push(issueObject);
  }
  var issueInfoSize = Object.keys(issueObjectList[0]).length;
  console.log(issueSize + "," + issueInfoSize)

  // シートをクリア
  ClearBeforeSheetInfo(ss);

  ss.getRange(2,1,issueSize,issueInfoSize).setValues(issueObjectList);
}

function ClearBeforeSheetInfo(sheet){
  var range = sheet.getRange("A2:X100");
  range.clear({contentsOnly: true});
}

function UpdateIssue(issueData){
  var assign = issueData['assignee']
  var labelName = issueData['labels']

  var issueList = []
  if(assign == null){
    issueList = [issueData['number'],issueData['title'],"修正中","指定なし",issueData['url']]
  }else{
    issueList = [issueData['number'],issueData['title'],"修正中",GetUserName(assign['login']),issueData['url']]
  }
  return issueList;
}

一時間ごとに自動更新を行う.

手動でissueの更新をスプレッドシートに更新していたのでは意味がないので,GASのトリガーで一定時間ごとにスクリプトを実行するように設定します.

トリガーの設定画面