読者です 読者をやめる 読者になる 読者になる

定期的に GitHub API を叩いて Slack にポストしたい (2)

前回 では PR 一覧を取得したが、ラベルでの絞込やコメントが追加されたかどうかを判定できていなかった。

PR のラベル、コメント数を取得

  • PR 取得の API ではラベルとコメントを取得できないので別途 API をたたく。
/// ある PR に付与されたラベルを取得する
function getLabels(number, owner, repo, options) {
  var url = "https://api.github.com/repos/" + owner + "/" + repo + "/issues/" + number + "/labels?per_page=100";
  var response = UrlFetchApp.fetch(url, options);
  var json = JSON.parse(response.getContentText());
  
  var labels = [];
  for (var i = 0; i < json.length; i++) {
    var hash = json[i];
    labels.push(hash["name"]);
  }
  
  return labels;
}

// コメント数を取得
function countComments(number, owner, repo, options) {
  var url1 = "https://api.github.com/repos/" + owner + "/" + repo + "/issues/" + number + "/comments?per_page=200";
  var response1 = UrlFetchApp.fetch(url1, options);
  var comments1 = JSON.parse(response1.getContentText());
    
  var url2 = "https://api.github.com/repos/" + owner + "/" + repo + "/pulls/" + number + "/comments?per_page=200";
  var response2 = UrlFetchApp.fetch(url2, options);
  var comments2 = JSON.parse(response2.getContentText());
  
  return comments1.length + comments2.length;
}

前回取得時のコメント数を保存

  • コメント件数を覚えておいて、前回の件数より増えていたら通知対象にする、などに使う。
// PR 単位にコメント件数を PropertiesService で覚えておき、前回実行時からの差分を取得する。
function getUpdatedInfo(number, commentCount) {

  var key = number;
  var oldPull = JSON.parse(PropertiesService.getScriptProperties().getProperty(key));
  
  // 新しく作成された、またはコメントが追加された PR 
  var isCreated = oldPull == null;
  if(isCreated || commentCount > oldPull.commentCount) {
    var value = JSON.stringify({ 
      "commentCount" : commentCount
    });
    PropertiesService.getScriptProperties().setProperty(key, value);
    
    // 新しく作成された PR
    if(isCreated) {
      return {
        "isCreated": true,
        "newCommentCount": commentCount
      };
    }
    
    // コメントが追加された PR
    return {
      "isCreated": false,
      "newCommentCount": commentCount - oldPull.commentCount
    };
  }
    
  // 既存でコメントが追加されていない PR
  return {
    "isCreated": false,
    "newCommentCount": 0
  };
}

解説や注意点など

  • ラベルの取得はそのまんま。 PR は issue の一種という扱いらしく、 issue の API は PR でも使える。らしい。
  • コメントは、本文へのコメント(issues)とレビューコメント(pulls)で別に計算されるらしいのでそれぞれで取得する。
  • PropertiesService を使うと key-value でデータを write/read できる。この値は、画面からも確認できて、 Google Apps Script の「ファイル - プロジェクトのプロパティ - スクリプトのプロパティ」で表示される。素敵!