자동화를 통한 효율적인 코드 리뷰 문화 만들기

코드 리뷰, 꼭 필요할까?

팀의 새로운 리드 개발자가 되면서 가장 먼저 마주한 것은 코드베이스의 현재 상태였습니다. 기존 팀원들이 떠나고 새로운 팀원들과 함께 프로젝트를 이어받게 되었는데, 코드를 분석하면서 몇 가지 어려움이 눈에 띄었습니다.

가장 큰 문제는 일관성 없는 코드 스타일이었습니다. 시간이 지나면서 여러 개발자들이 거쳐갔고, 각자의 스타일대로 작성된 코드들이 혼재되어 있었죠. 어떤 파일에서는 함수형으로, 또 다른 파일에서는 클래스형으로 작성된 컴포넌트들이 공존했고, 네이밍 컨벤션도 파일마다 제각각이었습니다.

이는 자연스럽게 유지보수의 어려움으로 이어졌습니다. 새로운 팀원들이 기존 코드를 파악하는 데 예상보다 훨씬 많은 시간이 필요했고, 간단한 버그 수정이나 기능 추가도 코드 이해에 많은 시간을 투자해야 했습니다. 주석도 충분하지 않아 코드의 의도를 파악하는 것도 쉽지 않았습니다.

“이대로는 안 되겠다”

새로운 팀원들과 함께 시작하는 시점에서, 이러한 문제들을 해결하기 위한 방안이 필요했습니다. 코드 리뷰 문화를 도입하면 단기적으로는 개발 속도가 늦춰질 수 있지만, 장기적으로 봤을 때 이는 우리 팀에게 꼭 필요한 투자라는 확신이 들었습니다.

첫 발걸음: 코드 리뷰 문화 도입

코드 리뷰 문화를 도입하기로 결정한 후, 가장 먼저 한 일은 팀원들과의 회의였습니다. 3명이라는 작은 팀 규모는 오히려 장점이 되었습니다. 모든 팀원이 자유롭게 의견을 나누며 우리 팀에 맞는 코드 리뷰 문화를 만들어갈 수 있었죠.

기초 다지기: 코드 컨벤션 정립

먼저 일관된 코드 스타일을 위해 ESLint와 Prettier 설정부터 시작했습니다.

// .eslintrc.js
module.exports = {
// ...
rules: {
'no-console': ['warn', { allow: ['warn', 'error'] }],
// 팀 내부에서 합의된 규칙들...
}

효율적인 리뷰를 위한 템플릿 작성

PR 템플릿도 만들었습니다. 리뷰어가 꼭 확인해야 할 부분을 명확히 하고, 작업 내용을 쉽게 파악할 수 있도록 구성했죠.

작업 내용

- [ ] 기능 추가/수정/삭제 여부
- [ ] 관련 Jira 티켓: [ABC-123]

리뷰 포인트

- 특별히 봐주었으면 하는 부분
- 고민했던 부분이나 다른 해결 방법

코드 리뷰 문화를 통한 변화

코드 리뷰 문화가 자리잡기 시작하면서 긍정적인 변화들이 나타났습니다. 예를 들어, 이전에는 이런 코드가 있었다면:

function getData(p) {
  const d = p.info;
  if (d) {
    return d.value;
  }
  return null;
}

코드 리뷰를 통해 이렇게 변경되었죠:

interface UserInfo {
  info?: {
    value: string;
  };
}

function getUserValue(userInfo: UserInfo): string | null {
  return userInfo.info?.value ?? null;
}

하지만 모든 것이 장밋빛은 아니었습니다. 코드 리뷰에 시간을 뺏기다 보니 개발 일정에 차질이 생기기도 했고, 특히 급한 수정사항이 있을 때는 리뷰 대기 시간이 답답하게 느껴졌습니다. 한 팀원은 이렇게 말하기도 했죠.

“어제 급하게 수정해야 하는 버그가 있었는데, 리뷰 답변을 기다리느라 배포가 늦어졌어요. 이런 상황에서는 어떻게 하는 게 좋을까요?”

이러한 현실적인 어려움들은 우리가 다음 단계로 나아가는 계기가 되었습니다.

현실의 벽: 코드 리뷰가 지연되는 이유

코드 리뷰 문화가 정착되어 가는 듯했지만, 여전히 큰 문제가 있었습니다. PR이 올라온 후 merge까지 걸리는 시간이 너무 길었죠. 문제의 원인을 정확히 파악하기 위해 팀원들과 1:1 미팅을 가졌습니다.

팀원들의 솔직한 이야기

미팅에서 나온 이야기들은 제가 생각했던 것보다 더 다양했습니다.

“테스트 코드가 없어서 이 코드가 정상적으로 작동하는지 확인하기가 너무 어려워요. PR 설명에는 잘 동작한다고 되어있는데, 실제로 확인하려면 제가 직접 실행해봐야 해서…”

“한 번에 너무 많은 코드가 변경되면 리뷰하기가 힘들어요. 어제 받은 PR은 30개 파일이 수정되었더라고요. 어디서부터 봐야 할지…”

“솔직히 말씀드리면, 제가 맡은 기능 개발하느라 바빠서 나중에 리뷰하려고 했는데 깜빡했어요. 메일이 와도 바로 확인을 못하다 보니…”

데이터로 보는 현실

문제를 더 객관적으로 파악하기 위해 네이버의 PR-stats를 참고해서 우리 팀의 코드 리뷰 현황을 분석해보았습니다.

// PR 응답 시간 분석 결과
*** user state ***
averageMergeTime: 2,
maxMergeTime: 4,

3개월간의 데이터를 분석한 결과, PR merge까지 평균 2일, 최대 4일까지 걸리는 것을 확인할 수 있었습니다. 하지만 3명이라는 작은 팀 규모에서 이 데이터만으로는 정확한 문제 진단이 어려웠습니다. 그래서 데이터를 활용하기 보단 1:1 미팅을 통해 파악된 것을 중점적으로 활용하기로 했습니다.

핵심 문제점 도출

1:1 미팅과 데이터 분석을 통해 도출된 주요 문제점들은 다음과 같았습니다:

  1. 검증의 어려움: 테스트 코드 부재로 인한 동작 검증의 어려움
  2. 과도한 변경사항: 한 번에 너무 많은 코드 변경
  3. 늦은 피드백: 리뷰어의 늦은 응답과 늦은 수정 반영
  4. 도메인 이해 부족: 다른 팀원의 작업 영역에 대한 이해도 차이

이러한 문제들을 해결하기 위해서는 보다 체계적인 접근이 필요했습니다. 특히 자동화를 통해 해결할 수 있는 부분들이 보이기 시작했죠.

더 나은 방향으로: 자동화를 통한 개선

문제 해결을 위해 우리가 선택한 방법은 자동화였습니다. 특히 Slack 알림, Draft PR 활용, 그리고 Danger JS를 통한 자동 코드 리뷰 시스템을 구축했습니다.

Slack 알림 자동화

먼저 GitHub Actions를 활용해 PR 상태 변경시 Slack으로 자동 알림을 보내도록 구현했습니다.

# .github/workflows/pr-slack-notification.yml
name: PR Slack Notification
on:
  pull_request:
    types:
      - synchronize
      - opened
      - reopened
      - ready_for_review
    branches:
      - develop

jobs:
  notification:
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Send notification
        run: node scripts/sendPRNotification.js
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

그리고 실제 알림을 보내는 로직은 별도의 스크립트 파일로 분리했습니다.

// utils/sendPRNotification.js
async function main() {
  // PR 작성자를 제외한 모든 팀원에게 DM 발송
  const reviewers = getReviewers(pull_request.user.login);

  await githubClient.rest.pulls.requestReviewers({
    owner: github.context.repo.owner,
    repo: github.context.repo.repo,
    pull_number: github.context.issue.number,
    reviewers: [...reviewers],
  });

  sendPRNotification();
}

function getReviewers(prAuthor) {
  // 팀원 목록에서 PR 작성자를 제외한 나머지 팀원 반환
  const teamMembers = [
    { githubId: "member1", slackId: "U1234567" },
    { githubId: "member2", slackId: "U7654321" },
    { githubId: "member3", slackId: "U1111111" },
  ];

  return teamMembers.filter((member) => member.githubId !== prAuthor);
}

function sendPRNotification() {
  const message = createMessage(github.context);

  // 프론트엔드 채널에 알림 메시지 보내기
  slackClient.chat.postMessage({
    text: message,
    channel: FrontEndSlackChannelId,
  });
}

Danger JS를 통한 자동 코드 리뷰

기본적인 코드 컨벤션에 대한 리뷰 시간을 단축하기 위해 Danger JS를 도입했습니다.

// danger.ts
async function checkPRSize(): Promise<void> {
  const { additions = 0, deletions = 0 } = danger.github.pr;
  const changes = additions + deletions;

  if (changes > 500) {
    warn("PR이 너무 큽니다. 가능하다면 더 작은 단위로 분리해주세요.");
  }
}

async function checkFormatting(): Promise<void> {
  const files: string[] = danger.git.modified_files.concat(
    danger.git.created_files,
  );

  const relevantFiles = files.filter((file) => /\.(ts|tsx|js|jsx)$/.test(file));

  for (const file of relevantFiles) {
    try {
      const { stdout, stderr } = await execAsync(
        `npx prettier --check "${file}"`,
      );
    } catch (error: any) {
      warn(`${file} 파일의 포맷팅이 필요합니다.`);
    }
  }
}

Draft PR 활용 전략

또한, 큰 변경사항이 있는 경우, PR 제목에 [DRAFT] 태그를 추가하여 리뷰어들이 쉽게 확인할 수 있도록 했습니다. 이를 통해 작은 단위로 리뷰를 진행할 수 있었습니다.

개선 효과

이러한 자동화 도구들을 도입한 후, PR merge까지 걸리는 시간이 평균 2일에서 1일 이내로 크게 단축되었습니다. 특히 Slack 알림 자동화는 즉각적인 효과를 보여주었는데, 팀원들의 반응도 긍정적이었습니다.

“이제는 PR이 올라오면 바로 알 수 있어서 좋아요. 특히 오후 2시 리마인더 덕분에 당일 리뷰를 놓치는 일이 거의 없어졌어요.”

“Danger JS가 기본적인 체크를 해주니까 리뷰할 때 코드 자체에 더 집중할 수 있게 되었어요.”

자동화는 단순히 시간을 절약하는 것을 넘어, 팀원들이 더 가치 있는 리뷰에 집중할 수 있게 해주었습니다.

마무리: 코드 리뷰, 그 이상의 가치

5개월이라는 시간 동안 코드 리뷰 문화를 정착시키면서 많은 것을 배웠습니다. 단순히 코드의 품질을 높이는 것을 넘어, 팀원들과의 소통과 학습의 기회가 되었죠.

우리가 얻은 것들

  1. 지식 공유의 장

    • 코드 리뷰를 통해 서로의 도메인 지식을 자연스럽게 공유
    • 주니어 개발자들의 성장 기회
    • 팀의 기술적 의사결정에 대한 이해도 향상
  2. 더 나은 코드베이스

    • 일관된 코드 스타일
    • 더 명확해진 네이밍과 구조
    • 버그 발생 가능성 감소
  3. 팀 문화의 성장

    • 더 활발해진 기술적 토론
    • 상호 신뢰 관계 형성
    • 자유로운 의견 제시

앞으로 개선하고 싶은 부분

물론 아직도 개선의 여지는 남아있습니다.

테스트 코드 작성, 긴급 PR에 대한 명확한 프로세스 정립 같은 부분들이 있죠.

마지막으로

코드 리뷰는 단순한 코드 검토 과정이 아닙니다. 이는 팀의 기술적 성장과 협업 문화를 만들어가는 중요한 도구입니다. 우리 팀은 이제 막 그 여정을 시작했고, 앞으로도 계속해서 발전시켜 나갈 예정입니다.

“좋은 코드를 작성하는 것도 중요하지만, 그 과정에서 함께 성장하는 것이 더 값진 것 같아요.”

라는 팀원의 말처럼, 코드 리뷰는 우리 팀에게 단순한 프로세스 이상의 의미를 가지게 되었습니다. 앞으로도 이 문화를 더욱 발전시켜 나가면서, 더 나은 개발팀으로 성장해 나가고 싶습니다.