7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wano GroupAdvent Calendar 2024

Day 23

GithubのPRコメント数を集計→Slack通知で賞賛の文化を作る

Last updated at Posted at 2024-12-22

はじめに

こちらはWano Group Advent Calendar 2024 の23日目の記事です。

きっかけ

TuneCore Japanのバックエンドエンジニア @tutti618です。

先日、チーム内で「普段行っているレビューやSlackへの反応数を目にみえるようして
賞賛できる文化があると良いね」という話になり、アドカレの題材にしてみました。

検討したのは下記3件

  • テスト環境でのバグ報告数
    何を持ってバグ報告とするのか、定義が難しいため今回は対象外

  • Slackのスタンプ反応数
    Slack APIを使わずとも、
    アナリティクス機能で閲覧可能のため今回は対象外
    Slack> アナリティクス > メンバー > 列を編集する > [追加されたリアクション数]をチェック > [追加されたリアクション数]でソート
    Slackアナリティクス.png

  • GithubのPRコメント数
    →レビューを積極的に行っていただいている方を賞賛できる🎉ということで
    今回はこちらを作ります!

まずはローカルで

Github Tokenの生成

注意
後述しますがこのscopeだとリポジトリに対して書き込みもできてしまうため
よりscopeを細分化して設定できるFine-grained personal access tokensを使う方がセキュアです。

Githubトークン5.png

scopeは下記にしました。
githubトークン.png

Slack WebHook URL発行のご依頼

権限のあるマネージャーに、Slack通知したいチャンネルに対して
Slack WebHook URLを発行していただきます。

スクリプトの作成

Github APIへのリクエストは@octokit/coreを使いますので
必要に応じてnpm install @octokit/core

calc.mjs
import { Octokit } from "@octokit/core";
import axios from "axios";
import dayjs from "dayjs";

// GitHub Personal Access Token
const TOKEN = "GitHubToken";
const WEBHOOK_URL =
  "Slack WebHook URL";

// リポジトリ情報
const OWNER = "owner"; // リポジトリのオーナー
const REPO = "reponame"; // リポジトリ名

const octokit = new Octokit({ auth: TOKEN });

async function postToSlack(formattedSummary, since) {
  const data = {
    text: "Weekly PR Comments Summary",
    attachments: [
      {
        fallback: "Weekly Summary",
        color: "#36a64f",
        pretext: `*Weekly PR Comments Summary*\n\n${formattedSummary}`,
        author_name: "Since",
        title: since,
        text: "からの集計",
      },
    ],
  };

  axios
    .post(WEBHOOK_URL, data)
    .then((response) => {
      console.log("Sended successfully");
    })
    .catch((error) => {
      console.error(error);
    });
}

async function getPRComments(owner, repo, since) {
  let page = 1;
  const perPage = 100;
  let comments = [];

  while (true) {
    const response = await octokit.request(
      "GET /repos/{owner}/{repo}/pulls/comments",
      {
        owner,
        repo,
        since,
        per_page: perPage,
        page,
      }
    );

    comments = comments.concat(response.data);

    if (response.data.length < perPage) {
      break;
    }
    page++;
  }

  return comments;
}

async function main() {
  // 過去1週間の日付を計算
  const since = dayjs().subtract(1, "week").toISOString();

  console.log(`Fetching PR comments since: ${since}`);

  // PR コメント取得
  const comments = await getPRComments(OWNER, REPO, since);

  // ユーザーごとの集計
  const userCommentCount = comments.reduce((acc, comment) => {
    const user = comment.user.login;
    acc[user] = (acc[user] || 0) + 1;
    return acc;
  }, {});

  // 結果を文字列型に変換
  const formattedSummary = Object.entries(userCommentCount)
    .map(([user, count]) => `- *${user}*: ${count} comments`)
    .join("\n");

  await postToSlack(formattedSummary, since);
}

main().catch((error) => {
  console.error("Error:", error.message);
});

実行

node calc.mjs

集計値が対象のSlackチャンネルに送信されました🎉
Slack送信.png

定期実行するための方針

上記では自分のローカルから、手動でしか実行できないため
毎週定期的に実行するための方針を3点検討しました。

  1. Slackアプリ上でBolt for JavaScriptを使用
    →Github TokenをSlack側に持つ必要があり、セキュリティ的にNG
  2. AWS Lambda + Amazon SNS + AWS Chatbot
    →ちょっと面倒
  3. Github Actions
    →マネージャーよりこちらをお薦めいただきました!

Github SecretにGithub TokenとSlack WebHook URLを登録

Github Actionsに直接Token情報を記載しないようにするため
権限のあるマネージャーに、対象のGithub リポジトリのsettingから設定いただきます。

Github Actionsの作成

時刻はUTCのため9時間早く設定します。(下記の例は毎週水曜10:00)

.github/workflows/pr-comments-summary.yml
name: Weekly PR Comments Summary

on:
  schedule:
    - cron: '0 1 * * 3'
  workflow_dispatch:

jobs:
  pr-comments-summary:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Set up Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'

    - name: Install dependencies
      run: yarn install

    - name: Fetch PR comments and send to Slack
      env:
        SLACK_WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
        GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }}
      run: |
        #!/usr/bin/env node
        以下、処理内容を記載

ですが、時間切れ、、、😔

対象リポジトリではyarnを使用しているのですが
こちらの依存関係解消ができず、今回は間に合いませんでした。。。

他にも改善点

  • Github Tokenが書き込みもできてしまうscope
    →Fine-grained personal access tokensを使う
    →こちらのtoken + @octokit/coreではGithub APIが404で呼べなかったため
    さらなる調査が必要💻
    Githubトークン4.png

githubトークン3.png

  • 自分、他の方のレビュー全然できてないのにコメント数多い…😎?
    →自分が作成したPRに対するコメントは計上しないようにしたい

最後に

今後は定期実行の問題を解決し、毎週のチームMTGなどで
コメント数をふりかえりできるようにしていきたいと思います!

アイディアをいただいた @gibomさん、@masafumi330さん
技術相談にのっていただいた @lulinさん、@shogoroyさん
お忙しい中、アドバイスいただきありがとうございました🙇‍♀

PR

現在、Wanoグループ / TuneCore Japan では人材を募集しています。
興味のある方は下記をご参照ください:information_desk_person:

Wano | Wano Group JOBS
TuneCore Japan | TuneCore Japan JOBS

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?