GASでmasterにマージされたプルリク一覧をSlackに投稿する


はじめに

GitHubのGraphQL API v4とGoogle Apps Scriptを使って、「今週masterブランチにマージされたプルリク一覧」取得&Slackに投稿してみました。

GitHub GraphQLのクエリを作る

公式のサンプルクエリ をベースに、 公式のGitHub GraphQL API Explorer で調整していきます。

プルリクの絞り込み

以下の条件で絞り込みます。

  • ベースブランチがmaster => baseRefName: "master"
  • プルリクがマージされている => states: MERGED
  • ついでに取得件数を20件に絞っておく => last:20

※参考  プルリクエストの絞り込みに使えるパラメータ

fieldの絞り込み

プルリクの全ての情報が欲しいわけではないので、以下のfieldだけに絞り込みます。

  • プルリクタイトル => title
  • プルリク作成者の名前 => author { login }
  • プルリクのURL => permalink
  • プルリクのマージ日 => mergedAt

※参考 プルリクエストのfield一覧

最終的なクエリ

こんなクエリが出来上がりました。

query { 
  repository(owner: "owner", name: "name") { 
    pullRequests(last: 20, states: MERGED, baseRefName: "master") {
      edges {
        node {
          title
          permalink
          mergedAt
          author {
            login
          }
        }
      }
    }
  }
}

GASでGitHub APIを使ってプルリクを取得&Slackに投稿

GitHub APIにPOSTする部分は今後も使いそうなので切り離しておきました。

function fetchFromGitHub(query) {
  var TOKEN = "token";
  var ENDPOINT = "https://api.github.com/graphql";

  var payload = JSON.stringify({
    "query": query
  });

  var options = {
    "method": "POST",
    "contentType": 'application/json',
    "headers": {
      "Authorization": "Bearer " + TOKEN
    },
    "payload": payload
  };
  return JSON.parse(UrlFetchApp.fetch(ENDPOINT, options));
}

取得後マージ日を見てフィルタ&整形してSlackに投稿しています。

function getMasterMergedBranchesInThisWeek() {
  var query = "{ \
    repository(owner: "owner", name: "name") { \
      pullRequests(last:20, states: MERGED, baseRefName: "master") { \
        edges { \
          node { \
            title \
            permalink \
            mergedAt \
            author { \
              login \
            } \
          } \
        } \
      } \
    } \
  }";
  var response = postGitHubAPI(query);
  var pullRequests = response.data.repository.pullRequests.edges.map(function (edge) {
    return edge.node;
  });

  // マージ日でフィルタ
  // 日付操作にはmoment.jsを使っています
  var startDate = moment().startOf('week');
  var recentMergedPullRequests = pullRequests
    .filter(function (pr) {
      return moment(pr.mergedAt).isSameOrAfter(startDate);
    });

  // 整形
  var text = "今週マージされたプルリク一覧\n";
  text += recentMergedPullRequests.map(function(pr) {
    return "" + pr.title + "(" + pr.author.login + "):" + pr.permalink;
  }).join("\n");

  postSlackMessage("channel_id", text);
}

Slackに投稿する部分も分離させてます。

function postSlackMessage(channel, text) {
  var TOKEN = "token";
  var ENDPOINT = "https://slack.com/api/chat.postMessage";

  var payload = {
    "text": text,
    "channel": channel,
    "token": TOKEN
  };
  var options = {
    "method": "POST",
    "payload": payload
  };
  return UrlFetchApp.fetch(ENDPOINT, options);
}

無事投稿できました。

おわりに

API v3と違って必要なfieldしか取ってこないので、レスポンスを出力したときに見やすくて良いですね。
GASではバッククォートが使えないので、query書く部分でバックスラッシュを多用しないといけないのが辛いなと思いました。

参考にさせていただきました

GitHub GraphQL API v4をGoogle App Scriptから実行してissue一覧を取得してみた