FORCIA CUBEフォルシアの情報を多面的に発信するブログ

TypeScript を使ってコードレビューを効率化するツールを作ってみた

2018.12.19

アドベントカレンダー2018 テクノロジー

FORCIAアドベントカレンダー2018 19日目の記事です。

 技術本部の武田です。今回の記事では、レビューフローの一部を自動化し効率化するツールを、 TypeScript を使って作成する方法をご紹介します。フォルシアではGitのリポジトリ管理にGitLabを利用しています。社内のリポジトリには大きく分けて次の2種類があります。

  • 各プロジェクト毎のリポジトリ
  • 社内共通ライブラリ、ツール類のリポジトリ

 このうち、社内共通で利用するライブラリ、ツール類のリポジトリを改修する場合は以下のようなレビューフローがあります。

  1. 改修をした人(レビュイ)は Merge Request (GithubでいうPull Request)を作成する
  2. レビュアを2人選定
  3. レビュイ、レビュア間でコードレビュー
  4. 完了後、リポジトリ管理者にレビュー完了を連絡
  5. マージ

 今回はマージリクエストの状態をチェックして、レビュアを選定する部分を自動化してみます。

今回作成するツールの処理の流れ

 以下のような処理フローにしました。

  1. assignee (レビュア) が設定されていない Merge Request の一覧を取得
  2. GitLab のユーザ一覧を取得し、ランダムに assignee を選出
  3. Merge Request の assignee を選出したユーザに設定
  4. Slack に通知

GitLab API を利用する

 GitLab では様々な API が用意されています。

 今回は、以下の3つを利用します。

  1. ユーザの一覧を取得する Users API
  2. プロジェクトの情報を取得する Projects API
  3. Merge Resuest の情報を取得や assignee を変更するために Merge requests API

 直接APIを実行しても問題なさそうですが、GitLab の API を wrap してくれた npm package があったのでこちらを利用してみました。

 ユーザの一覧、および assignee が設定されていない Merge Request は以下のように取得できました。

// active なユーザを取得する
const activeUsers = await api.Users.all({ active: true });

 今回は特定のプロジェクトにおける Merge Request に絞るため、プロジェクトの ID を取得します。

const projects = await api.Projects.search("プロジェクト名");
const targetProject = projects.find(
    (project: any) =>
        project.namespace.name === "グループ名" && project.name === "プロジェクト名"
);
const projectId = targetProject.id;

 対象のプロジェクトの Merge Requests のうち assignee の設定がないものは以下のように取得できます。

// opened の Merge Requests のうち assignee の設定がないものを取得する
const unassignedMergeRequests = await api.MergeRequests.all({
    projectId,
    state: "opened",
    assignee_id: 0
});

 上記で取得した Merge Requests に対してランダムにユーザを設定する場合は次のようにできます。

unassignedMergeRequests.forEach(async (mergeRequestInfo: any) => {
    // ランダムにユーザを選出
    const randomUser =
        activeUsers[Math.floor(Math.random() * activeUsers.length)];
    // 対象の Merge Request の iid を取得
    const mergeRequestIid = mergeRequestInfo.iid;
    // 対象の Merge Request を編集し、assignee をランダムに選出したユーザに変更
    await api.MergeRequests.edit(projectId, mergeRequestIid, {
        assignee_id: randomUser.id
    });
});

 非常に簡単にユーザの一覧取得、assignee の設定されていない Merge Request の取得、assignee の設定ができました。GitLab の API を利用して、色々な業務改善ができそうです。

Slack に通知する

 assignee がこのツールで設定された場合に Slack の Incoming Webhook を利用して通知するようにしてみました。こちらも簡単に実装できます。

const payload = {
    fallback: `レビュー依頼: ${mergeRequestTitle}`,
    pretext: `プロジェクト名: <${projectUrl}|${projectName}>`,
    color: "good",
    fields: [
        {
            title: "レビュー依頼",
            value: `<@${assignee}> <${mergeRequestUrl}|${mergeRequestTitle}>のレビューをお願いします`
        }
    ]
};
const resp = await fetch(webhookUrl, {
    method: "post",
    body: `${JSON.stringify(payload)}`
});
const resultText = await resp.text();

 以下が通知例です。

FireShot Capture 31 - test_takeda I forcia Slack_ - https___forcia.slack.com_messages_.png

さいごに

 非常に簡単に GitLab API を利用して便利なツールを作成することができました。今回はランダムにユーザを選出しましたが、どのユーザが適切かを判別するアルゴリズムを導入するのも良さそうです。

 他にも

  • 一定期間動きのないチケットを通知する
  • thumbs up sign が2人以上から付いていたら「マージできます」とリポジトリ管理者に通知する


などなど便利そうな機能がたくさん思い浮かびます。日々改善を加えて業務効率をアップしてくれるツールに仕上げていきたいです。

 フォルシアではこうした業務効率の改善に興味のあるエンジニアも募集しています。お気軽にご連絡いただければと思います。

エントリーをご希望の方:採用応募フォーム

採用に関するご質問・面談をご希望の方:採用お問い合わせフォーム
この記事を書いた人

武田陽一郎

2012年新卒入社 エンジニア
大手旅行会社の検索サイト開発を担当。
最近はスマートホームの構築にハマっている。