はじめに
こちらはWano Group Advent Calendar 2024 の23日目の記事です。
きっかけ
TuneCore Japanのバックエンドエンジニア @tutti618です。
先日、チーム内で「普段行っているレビューやSlackへの反応数を目にみえるようして
賞賛できる文化があると良いね」という話になり、アドカレの題材にしてみました。
検討したのは下記3件
-
テスト環境でのバグ報告数
何を持ってバグ報告とするのか、定義が難しいため今回は対象外 -
Slackのスタンプ反応数
Slack APIを使わずとも、
アナリティクス機能で閲覧可能のため今回は対象外
Slack> アナリティクス > メンバー > 列を編集する > [追加されたリアクション数]をチェック > [追加されたリアクション数]でソート
-
GithubのPRコメント数
→レビューを積極的に行っていただいている方を賞賛できる🎉ということで
今回はこちらを作ります!
まずはローカルで
Github Tokenの生成
注意
後述しますがこのscopeだとリポジトリに対して書き込みもできてしまうため
よりscopeを細分化して設定できるFine-grained personal access tokensを使う方がセキュアです。
Slack WebHook URL発行のご依頼
権限のあるマネージャーに、Slack通知したいチャンネルに対して
Slack WebHook URLを発行していただきます。
スクリプトの作成
Github APIへのリクエストは@octokit/coreを使いますので
必要に応じてnpm install @octokit/core
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
定期実行するための方針
上記では自分のローカルから、手動でしか実行できないため
毎週定期的に実行するための方針を3点検討しました。
- Slackアプリ上でBolt for JavaScriptを使用
→Github TokenをSlack側に持つ必要があり、セキュリティ的にNG - AWS Lambda + Amazon SNS + AWS Chatbot
→ちょっと面倒 - Github Actions
→マネージャーよりこちらをお薦めいただきました!
Github SecretにGithub TokenとSlack WebHook URLを登録
Github Actionsに直接Token情報を記載しないようにするため
権限のあるマネージャーに、対象のGithub リポジトリのsettingから設定いただきます。
Github Actionsの作成
時刻はUTCのため9時間早く設定します。(下記の例は毎週水曜10:00)
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で呼べなかったため
さらなる調査が必要💻
- 自分、他の方のレビュー全然できてないのにコメント数多い…😎?
→自分が作成したPRに対するコメントは計上しないようにしたい
最後に
今後は定期実行の問題を解決し、毎週のチームMTGなどで
コメント数をふりかえりできるようにしていきたいと思います!
アイディアをいただいた @gibomさん、@masafumi330さん
技術相談にのっていただいた @lulinさん、@shogoroyさん
お忙しい中、アドバイスいただきありがとうございました🙇♀
PR
現在、Wanoグループ / TuneCore Japan では人材を募集しています。
興味のある方は下記をご参照ください