개발 기술/개발 이야기

내 조직의 리뷰 할당 현황 구하기(1) - github API 사용법

by GicoMomg 2023. 6. 19.

0. 들어가기에 앞서…

  • 우리 개발팀은 코드 리뷰를 통해 코드의 품질을 유지하고 개발자들의 성장을 돕는 걸 중요하게 생각한다.
  • 대체적으로 리뷰는 매일 오후 2시 전에 완료하고, 한 사람에게 많은 리뷰를 할당하는 건 지양하지만…

  • 때로는 한 사람이 많은 리뷰를 받는 경우도 있다. 이는 개인의 선호도나 코드 이해도 등의 이유로 인해 발생할 수 있다. 이러한 상황은 리뷰어가 자신의 작업을 진행할 시간이 적어지게 만들고 일정 지연을 초래할 수 있다.
  • 또한 리뷰어가 다른 작업으로 바쁜 날에는 할당된 리뷰를 놓치는 경우가 있는데, 개발자들이 리뷰를 기다리는 시간이 길어지게 만든다.

 

  • 마침 우리 팀은 Discord를 팀챗으로 사용하고 있었는데, 이 두가지 현상을 해결하고자 “Discord webhook을 사용하여 매일 아침 9시에 리뷰 할당 현황을 메시지로 전송”하는 코드를 만들었다!
  • 해당 메시지로 개발자는 본인이 리뷰어인지 알 수 있고, 한 사람에게 많은 리뷰가 할당되지 않았는지도 알 수 있다.

 

  • 코드의 경우 github API, discord webhook 그리고 github actions를 사용했으며,
  • 3가지 기술을 한 포스팅으로 설명하긴 어려워 “내 조직의 리뷰 할당 현황 구하기” 시리즈를 만들었다.
  • 시리즈는 아래와 같이 총 3가지로 구성했다.

😎 시리즈 순서

(1) github API로 내 조직의 리뷰 할당 현황 구하기
(2) discord webhook을 사용하여 discord 채널에 할당 현황 데이터를 전송하기(포스팅 링크)
(3) github actions로 discord webhook 주소에 자동으로 할당 현황 메시지 전송하기(포스팅 링크)

  • 이 시리즈를 다 공부하게 되면, 아래 이미지와 같이 리뷰 할당 현황을 디스코드로 자동 전송할 수 있다.
  • 이번 포스팅에서는 ”(1) github API로 내 조직의 리뷰 할당 현황 구하기”를 알아보았다.




1. github API로 내 조직의 리뷰 할당 현황 구하기

1) 토큰 발급 받기

  • 내 조직(org)의 리뷰 할당 현황을 알기위해선 github auth token이 필요하다.
  • 우선, github에서 우측 프로필을 클릭하여 [Settings]로 이동한다.

 

  • 그 다음 좌측 하단에 있는 [Developer Settings]를 클릭한다.

 

  • [Personal access tokens]에서 [Tokens (classic)] 로 이동한 후, 우측의 [Generate new token] 버튼을 클릭한다.

 

  • 그 다음에 토큰 이름, 토큰 만료일 토큰 옵션을 차례로 지정하고 토큰을 저장하자.

 

  • 이때 토큰의 옵션 중에서 아래 3가지는 필수로 선택해주자.
토큰 옵션  옵션 설명
repo  private 레포 접근 권한
read:org  조직 및 해당 팀에 대한 읽기 권한을 활성화
workflow  actions를 실행하는 권한

 

  • 토큰을 생성하면 현재 토큰값이 잠시 나타나는데 이때 꼭!! 기억해야한다.
    (지금 저장안하면 다시 생성해야함ㅜ)



2) github API로 리뷰 할당 현황 가져오기

  • 토큰을 획득하여 이제 github API를 사용하여 필요한 정보에 접근할 수 있게 되었다.
  • 이제 내 조직의 리뷰 할당 현황 정보를 알기 위해 github API를 사용해보자!
  • 큰 흐름은 다음과 같다.
순서  설명
1  github API를 사용해 조직(org)의 레포 목록을 가져온다.
2  그 다음 github API로 각 레포의 정보에 접근하여 리뷰 할당 정보를 가져온다.
3  마지막으로 정보를 원하는 형태로 가공한다.

 

(1) 프로젝트 기본 설정하기

  • 시작에 앞서 프로젝트 기본 설정을 해주자~!
  • 이번 프로젝트는, 노드 환경에서 진행하기에 yarn init을 사용해 프로젝트 초기 설정을 한다.
yarn init

 

  • 그리고 ES6방식의 import, export 사용을 위해 package.json에 "type": "module"를 추가한다.
// package.json
{
  "name": "discord-review-assign-webhook",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",   // 추가!
}

 

  • 프로젝트 구조의 경우, msg/pr-assign.js에 리뷰 할당 현황 코드를 담고
  • index.js에서 리뷰 할당 현황 코드를 호출할 예정이다.

 

  • 그러므로 packages.json에 index.js를 실행하는 스크립트도 추가해주자.
// package.json
{
  "name": "discord-review-assign-webhook",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module", 
  "scripts": {
    "serve": "node index.js",  // 추가!
  }
}

 

(2) dotenv로 중요 정보를 별도 관리하기

  • github API를 사용하기 위해 우리는 앞서 토큰을 발급받았다.
  • 그러나 이 토큰은 외부에 노출되면 안 되는 중요한 정보기에 별도 파일에 관리해야 한다.
  • dotenv.env 파일에 정보를 환경변수로 저장하여 관리하는 패키지이다.
  • 우리는 dotenv를 설치해 토큰 정보를 .env 파일에 저장하고, process.env로 변수값에 접근해야 한다.
  • 먼저 dotenv 패키지를 설치한다.
yarn add dotenv

 

  • 그리고 앞서 발급 받은 토큰 정보를 .env 파일에 저장한다.
// .env

AUTH_TOKEN=발급한_값

 

  • .env 파일을 깃헙에 push하지 않도록 .gitignore 파일에 .env를 추가한다.
// .gitignore

.env

 

  • .env 파일에 저장한 정보는 아래와 같이 process.env로 사용해 접근할 수 있다.
import "dotenv/config";                  // dotenv를 import해야 접근 가능

console.log(process.env.AUTH_TOKEN);    // 토큰_값

 

(3) github API로 조직(org)의 레포 목록 가져오기

😎 본격적으로 github API를 사용해 리뷰 할당 정보에 접근해보자!
((3) 부터 소개하는 코드는 msg/pr-assign.js의 코드임)

  • 먼저 github API를 사용하기 위해 @octokit/core 를 설치한다.
yarn add @octokit/core

 

  • new Octokit.env 파일에 저장한 토큰을 인자로 넘겨 api 요청 준비를 한다.
// msg/pr-assign.js

import { Octokit } from "@octokit/core";

const octokit = new Octokit({ auth: process.env.AUTH_TOKEN });

 

  • octokit 객체로 github API를 호출하여 조직의 레포 이름을 가져온다.
  • per_page값을 100으로 지정하여, 한 번에 100개의 레포 정보를 가져오도록 했다.
async function _getRepoNames() {
  // if your ora has more than 100 repos, you need to change this value
  const PER_PAGE = 100;
  const { data } = await octokit.request("GET /orgs/{org}/repos", {
    org: '내가_속한_조직_이름', 
    per_page: PER_PAGE,
  });
  return data.map((v) => v.name);
}

 

(4) github API로 각 레포의 리뷰 할당 정보를 가져오기

  • 앞서 _getRepoNames()에서 리턴한 레포 이름 정보로, 각 레포의 리뷰 할당 정보를 가져와야 한다.
  • 우선 각 레포별 리뷰 할당 정보에 리턴하는 _getRepoAsssigneers를 만든다.
// 해당 레포의 PR에 지정된 리뷰어 목록을 리턴함

async function _getRepoAsssigneers(repoName) {
  const { data } = await octokit.request("GET /repos/{owner}/{repo}/pulls", {
    owner: '내가_속한_조직_이름',
    repo: repoName,
  });
  return data.map((v) => v?.requested_reviewers);
}

 

(5) 사용자별 PR 할당수 계산하기

  • _getPRCountMap()는 사용자별 PR 할당 수를 카운팅하는 함수이다.
  • _getPRCountMap()에서 _getRepoAssignees()를 사용해 레포별 리뷰어 정보를 수집하고, 사용자별 PR 할당 수를 카운팅해주었다.
async function _getPRCountMap(repoNames) {
  if (!repoNames.length) return;
  const countMap = {};

  // 레포별 리뷰어정보 접근
  const assigneerList = await Promise.all(
    repoNames.map((repoName) => _getRepoAsssigneers(repoName))
  );

  // 유효한 사용자만 필터링
  const filteredList = assigneerList.map((data) =>
    data
      .flat()
      .map(({ login }) => login)
      .filter(Boolean)
  );

  // 각 사용자별로 PR 수 계산
  filteredList.flat().forEach((login) => {
    countMap[login] = (countMap[login] || 0) + 1;
  });
  return countMap;
}

 

(6) 데이터 가공하기

  • _getPRCountMap에서 반환된 정보를 리뷰 할당 개수에 따라 내림차순으로 정렬한다.
function _getFormattedMsg(data) {
  const sortedEntries = Object.entries(data).sort((a, b) => b[1] - a[1]);
  const formattedCountMap = sortedEntries.map(
    ([key, value]) => `- ${key}: ${value}`
  );
  return formattedCountMap.join("\n");
}

 

(7) 함수 합쳐서 호출하기

  • 마지막으로 앞서 만들었던 함수들을 하나의 함수로 합치고 함수를 export해주자!
export async function getMessage() {
  const repoNames = await _getRepoNames();            
  const countMap = await _getPRCountMap(repoNames);
  return _getFormattedMsg(countMap);
}

export default { getMessage };

 

(8) 명령어로 데이터 접근하기

  • index.jsmsg/pr-assign.jsgetMessage()를 호출하는 코드를 추가한다.
// index.js

import PRAssign from "./msg/pr-assign.js";

async function init() {
  const msg = await PRAssign.getMessage();
  console.log(msg);
}

init();

 

  • 그리고 터미널에 yarn serve를 하면, 터미널에서 결과를 확인할 수 있다.
yarn serve
// 리턴 데이터 형태

- KumJungMin: 3
- user1: 3
- user2: 2
- user1: 1




이번 시간에는 github API를 사용해 내 조직의 리뷰 할당 현황을 가져오는 방법을 알아보았다.
우선 github API 사용을 위해 토큰을 발급받아야 했으며 토큰의 보안을 위해 dotenv를 사용했다.
그 다음으로, github API를 사용하여 조직 내 레포지토리 목록을 가져왔다.
다음 시간에는 이 데이터를 discord webhook 주소로 전송하는 방법(링크)을 알아보도록 하겠다.

이번 포스팅에서 사용한 코드는 아래 링크에서 확인 가능하다
GitHub - KumJungMin/discord-review-assign-webhook at 1.github-api

 

반응형

댓글