STERFIELD

2023/07/14

GitHubリポジトリからIssueを取得してスプレッドシートに追記するGAS試作版を作ってみた

GitHubリポジトリからIssueを取得してスプレッドシートに追記するGAS試作版を作ってみた

はじめに

この記事では、GitHubのリポジトリからステータスが"OPEN"のIssueを取得し、Googleスプレッドシートに追記する方法を紹介します。GitHubのREST APIを使用し、Google Apps Scriptを使って自動化します。これにより、特定の組織の複数のリポジトリからIssue情報を一括で取得し、追加の作業なしでスプレッドシートに保存できます。

ということで、前回の記事でGoogle Apps Script(GAS)をChatGPTに書いてもらったのですが、さまざまなことができることが分かったので、実際に業務で使っているGitHubとの連携を試してみました。 いくつか課題は残ったものの基本的な動作は確認できたのでそのGASそのものもシェア致します。

https://sterfield.co.jp/blog/18162/

必要なもの

GitHubアカウントとアクセストークンの作成

GitHub >Setting>Developer Settings> personal access tokens >Fine-grained tokens を選択します。 ここから新しいトークンを発行するのですが、我々の管理では、リポジトリは組織に紐づいているので、組織に対してのトークンと必要な権限、リポジトリのIssueの読み取り権限を設定します。

Googleスプレッドシートの作成

最後にGASを共有していますが、スプレッドシートのIDが必要になります。 以下のようにd/と/editの間のXXXの値がスプレッドシートのIDになるので、控えておきしょう。

https://docs.google.com/spreadsheets/d/XXX/edit

Google Apps Scriptのセットアップ

スプレッドシート>拡張機能>Apps Scriptで開いたページのコード.gs欄にベタっと貼り付けます。

リポジトリの取得

ここから先のコードは、全てChatGPTから取得した末尾にシェアしているものを記載します。

GitHubのREST APIを使用して指定した組織のリポジトリを取得する関数を作成する リポジトリの一覧を表示するためのスプレッドシートの作成

Issueの取得と追記

取得したリポジトリごとにステータスが"OPEN"のIssueを取得する関数を作成する スプレッドシートにIssue情報を追記する

実行と結果確認

Google Apps Scriptの実行方法とトリガーの設定 スクリプトを実行し、Issue情報がスプレッドシートに追記されることを確認する

以下のように、取得はできたものの課題を残す結果となったので、課題点は後述します。

エラーハンドリングの追加と問題解決のヒント

エラーが出たら、そのエラー文言をChatGPTに投げ、修正コードをもらっていくのですが、こんなお茶目な一面も。

課題点

  • 一度に取得できるIssueを増やす。ページングの実装なども追加したが、全件取得には至らなかった。この点は、GraphQLの書き方をChatGPTが提案してくれたが、どうにも上手くいかず、今回はREST APIでの手法となった。
  • Projectsから課題を取得できないか。これは、Projectsがベータ版となっており、ChatGPTが2021年9月までの情報に留まっているため、断念。
  • シート内の重複削除。そもそも全件取得が出来ていないので、未検証。

まとめ

この記事では、GitHubのREST APIとGoogle Apps Scriptを活用して、GitHubリポジトリからステータスが"OPEN"のIssueを自動的に取得し、Googleスプレッドシートに追記する方法を紹介しました。これにより、開発チームやプロジェクト管理者は、リポジトリ内のオープンな課題を一元管理し、効果的に追跡することができます。さらに、自動化されたプロセスにより、作業の効率化とヒューマンエラーの軽減も期待できます。是非、この方法を試してみてください。

本当に革命的だなと思うのは、今までエンジニアに依頼するしかなかったような作業が非エンジニアである人間とChatGPTとの会話だけで出来てしまうところです。そして、このやり取りをしながら、指示を変えたりデバッグしていく作業はとても楽しいものでした。

そして、結構な時間をChatGPTと向き合ってきて、コツが分かってきたのですが、何かコードをもらう時に、一気に指示を出すのではなく、最初は最小単位で指示を出し、成功したら少しずつ機能を追加していくと、結局は近道です。 今回のケースですと、まずは、Githubから特定のリポジトリのIssueを取得。これが成功したら、ステータスをオープンに限定、複数のリポジトリから取得する、スプレッドシート側の重複をチェックするというように足していくと良かったです。

最後に今回のGASをシェアします。トークンやスプレッドシートのIDなどは、置き換えてください。

GAS

1// カスタムメニューを作成する関数 2function onOpen() { 3 var ui = SpreadsheetApp.getUi(); 4 ui.createMenu('Custom Menu') 5 .addItem('Fetch and Append Issues', 'fetchAndAppendIssues') 6 .addToUi(); 7} 8function fetchAndAppendIssues() { 9 var organization = "your_organization"; // 組織名 10 var spreadsheetId = "your_spreadsheet_id"; // スプレッドシートのID 11 var sheetName = "your_sheet_name"; // 追加するシートの名前 12 var status = "open"; // 取得するIssueのステータス 13 var perPage = 100; // 1回のリクエストで取得するIssueの数(最大100件) 14 15 var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName); 16 17 var repositories = getRepositories(organization); 18 var newData = []; // 新しいデータを格納する配列 19 20 for (var i = 0; i < repositories.length; i++) { 21 var repo = repositories[i]; 22 var page = 1; // ページ番号 23 24 while (true) { 25 var url = "https://api.github.com/repos/" + organization + "/" + repo + "/issues?state=" + status + "&per_page=" + perPage + "&page=" + page; 26 var response = UrlFetchApp.fetch(url, { 27 headers: { 28 "Authorization": "Bearer YOUR_GITHUB_ACCESS_TOKEN" // GitHubのアクセストークン 29 } 30 }); 31 32 var issues = JSON.parse(response.getContentText()); 33 if (issues.length === 0) { 34 break; // ページの結果が空ならループを終了 35 } 36 37 for (var j = 0; j < issues.length; j++) { 38 var issue = issues[j]; 39 var title = issue.title; 40 var number = issue.number; 41 var createdAt = issue.created_at; 42 var htmlUrl = issue.html_url; 43 44 newData.push([title, number, createdAt, htmlUrl]); // 新しいデータを配列に追加 45 } 46 47 page++; // 次のページに進む 48 } 49 } 50 51 if (newData.length > 0) { 52 if (sheet.getLastRow() === 0) { 53 sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData); // データを直接書き込む 54 } else { 55 sheet.getRange(sheet.getLastRow() + 1, 1, newData.length, newData[0].length).setValues(newData); // データを追記 56 } 57 } 58} 59 60function getRepositories(organization) { 61 var url = "https://api.github.com/orgs/" + organization + "/repos"; 62 var response = UrlFetchApp.fetch(url, { 63 headers: { 64 "Authorization": "Bearer YOUR_GITHUB_ACCESS_TOKEN" // GitHubのアクセストークン 65 } 66 }); 67 68 var repositories = JSON.parse(response.getContentText()); 69 var repoNames = []; 70 71 for (var i = 0; i < repositories.length; i++) { 72 var repo = repositories[i]; 73 repoNames.push(repo.name); 74 } 75 76 return repoNames; 77}

Author Profile

著者近影

YUJI MEZAKI代表取締役副社長

代表取締役副社長をやっています。 越境ECとWebマーケの営業担当しています。 なんでもカリカリにチューニングして生産性あげるのが好きで勉強したビジネスフレームワークの記事多め。 趣味はPC自作で会社のWindowsデスクトップはほぼ自分が組みました。 1985年生/2008年早大卒/

SHARE

合わせて読みたい