これは何か

GitHub Issueに起票したものをスプレッドシートに転記するシステムを制作したため、制作方法を記事にします。

使用したサービスやAPI

  • Google スプレッドシート
  • Google Apps Script
  • GitHub Issue
  • issue取得API

機能

  • issue取得APIを利用してgithub issueに起票されているissueを取得し、スプレッドシートに転記
  • issue番号、タイトル、ラベル、マイルストーン、担当者、状態、issueURLを転記
  • スプレッドシートの関数を使用して状態がcloseになっているissueは、行全体を灰色にして完了していることが分かるようにする
  • トリガーを時間に設定し、1時間ごとにスプレッドシートの更新を行う

スプレッドシート

スプレッドシートには以下の項目を転記しています。

  • issue番号
  • issueタイトル
  • ラベル
  • マイルストーン
  • 担当者
  • 状態
  • 最終更新日時
  • issue URL

Google Apps Script

GASにコードを書き始める前にGithubでアクセストークンを発行しておく。
参照:個人用アクセストークンの作成

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<br />//Github issue取得APIを利用してissueを取得する
function GetOpenIssues() {
var OWNER = 'リポジトリのオーナー名';
var REPO = 'リポジトリ名'
 
var url = 'https://api.github.com/repos/' + OWNER + '/' + REPO + '/issues?state=all&sort=created';
var accessToken = '発行したアクセストークン';
var headers = {
'Authorization': 'token '+ accessToken
};
 
var options = {
'method': 'GET',
'headers': headers,
};
var response = UrlFetchApp.fetch(url, options).getContentText();
var data = JSON.parse(response);
return data;
}
 
//転記を実行する
function UpdateGSheet(issueDataList) {
issueDataList = GetOpenIssues();
var sheetId = '転記したいスプレッドシートのID';
var sheetName = '転記したいシート名';
var ss = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
 
var issueObjectList = []
var issueSize = Object.keys(issueDataList).length;
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;
 
// シートをクリア
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 number = issueData['number'];
var title = issueData['title'];
var updated_at = new Date(issueData['updated_at']);
var jst_updated_at = Utilities.formatDate(updated_at, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss');
var state = issueData['state'];
if(issueData['assignee']){
var assign = issueData['assignee']['login']
} else {
assign = '指定なし'
}
if(issueData['milestone']){
var milestone = issueData['milestone']['title']
} else {
milestone = ''
}
var labelNames = "";
for (var i = 0; i < issueData['labels'].length; i++) {
//ラベルを全て取得してカンマ区切りで格納
labelNames += issueData['labels'][i]['name'] + ",";
}
//カンマが一つ余分なので、余分なカンマを削除
labelName = labelNames.slice(0, -1);
 
var issueList = []
issueList = [
number,
title,
labelName,
milestone,
assign,
state,
jst_updated_at,
issueData['url']
]
return issueList;
}