코드 리뷰 이야기(1)
이번 글과 다음 글은 올해 합류한 북경 개발 팀에 코드 리뷰를 적용하면서 개발팀의 상황에 따라 어떻게 적용해나가고 있는지, 어떤 관점으로 접근하고 있는지에 대해 공유하려고 합니다. 본론으로 들어가기에 앞서 코드 리뷰에 대한 정답은 없고 이런 사례는 지극히 제가 현재 있는 조직에만 국한된 이야기임을 강조하려고 합니다. 그래서 미리 서론에 코드 리뷰 적용하기 전의 개발팀의 상황에 대해 간단하게 정리하였습니다. 이글은 "Micro Service, Docker로 할 수 밖에 없었던 사연" 에서 이어진 글입니다.
첫번째 글에서는 코드 리뷰를 개발팀에 어떻게 적용했는지에 대해 소개하고 두번째 글에서는 실제 코드 리뷰를 수행 했던 내용에 대해 공유하겠습니다.
개발팀의 상황
2017년 초 제가 처음 합류했을 때 개발팀 및 개발 관련 프로세스 상황은 대략 다음과 같았습니다.
- 이슈 기반의 개발을 전혀 하고 있지 않음
- 구두, 메신저, 메일, 위키 등으로 업무가 할당되고, QA 팀에서 발견하거나 운영 중에 발생한 버그 등도 동일한 상황
- 코드 또는 설계에 대한 리뷰 과정은 없음
- 서비스간 인터페이스만 정의하고 인터페이스 스펙만 만족하면 OK
- 타 서비스 또는 다른 개발자가 만든 코드, 서비스에 대해서는 신경 안씀
- 형상관리 도구로 git을 사용하고 있지만 개발자가 직접 upstream으로 push 하고 있음
- git을 subversion 과 같은 형태로 사용
- 브랜치를 생성하지 않음
- 이런 상황은 서비스가 대부분 작게 쪼개어져 대부분의 프로젝트 레포지토리는 한명의 개발자에 의해 개발되고 있기 때문
- 기존 Stored Procedure, C/S 개발 환경에서 웹 기반 개발로 전환 후 1년이 지났지만 개발팀의 프로그램 개발 자체에 대한 역량은 많이 향상되지 않음
- 서비스 운영, 구성 등에 대한 역량은 좋아짐
- 프로그램 그 자체를 만드는 것이나 모델링 자체에 대한 역량이 향상되지 않음
- 소스 코드의 품질 관리가 안되고 있음
- 서비스 자체 기능에 대한 품질은 별도 테스트 팀을 통해 출시 전에 기능 테스트를 수행하고 있어 기본 품질은 보장되고 있음
- 하지만 소스 코드내에 엄청나게 많은 중복코드가 존재하고 변수명, 모듈화 등에 대해서는 고민하지 않음
- 현재 운영 되는 서비스뿐만 아니라 신규로 개발해야 하는 기능이 훨씬 더 많은 상황
- 현재 서비스 되는 기능들도 6/18, 11/11 등의 행사에 평소대비 5 ~ 10배 이상의 트래픽에 대응해야 하기 때문에 지속적인 튜닝 및 개선이 필요
- 신규 서비스는 계속 만들어지고 기존 서비스도 신규 서비스에 맞추어 개선 필요
- 좋은 개발자를 채용하기 어려움
- 많은 회사들이 겪고 있는 공통적인 문제이지만 여기 개발팀도 좋은 개발자를 뽑은 것은 현재 상황에서는 불가능
개발팀원되기
이글을 작성하고 있는 지금은 개발팀의 상황을 많이 파악해서 위와 같이 정리 가능했지만 초기에는 아무것도 모르는 상황이었고 관리자들의 의견만 듣는 수준이었습니다. 이 상태에서 무언가 개선하는 것을 결정하는 것보다는 개발팀의 상황 파악이 먼저라고 생각하였습니다. 그래서 결정한 사항이 저 또는 방안을 만들어야 하는 사람이 서비스 개발에 직접 참여하여개발, 배포, 운영까지 해보는 것이었습니다. 중국어 의사 소통 등의 문제로 인해 여러 개발자와 같이 하면 커뮤니케이션의 복잡도가 증가할 것 같아 의사 소통이 가능한 개발자 한명(힘들지만 영어로) 과 같이 진행하였습니다.
이렇게 결정한 계기 중의 하나는 앞에서 설명한 개발팀의 상황에서 새로운 것을 받아 들이거나 관심을 가질 여유가 없어 보였기 때문이기도 합니다. 그렇다고 현 상태로 계속 두면 개발자의 개발 역량은 올라가지 않을 뿐더러, 개발팀의 전체의 역량도 제자리인 상태로 유지될 것이라는 것은 뻔해 보였습니다. 그렇다고 좋은 개발 인력을 추가로 투입할 수 없는 상황이었습니다. 처음부터 무언가를 적극적으로 시작하기 보다는 조금 더 관찰해보기로 하고 특정 모듈을 직접 개발해보기로 했습니다.
이 과정에서 제가 개발하는 시스템과 연관이 있는 주변 시스템들의 코드를 보거나 개발자와 소통을 하면서 개발 프로세스와 개발자들의 생각, 개발에 있어 무엇을 더 중요하게 생각하는 지 등에 대해 파악을 하게 되었습니다. 이런 활동과 함께 Hadoop 기반으로 분석에 필요한 데이터를 통합 하면서 전체 시스템의 구조나 데이터 관계를 정리하면서 시스템 전반에 대한 이해도를 높여 나갔습니다.
이렇게 중국 개발자 한명과 개발을 진행하면서 저와 함께 일반적인 개발 프로세스를 적용해 보았습니다. 어떤 반응을 보일지, 잘 따라올 수 있는지에 대한 일종의 실험이었습니다.
조금씩 녹여나가기
2 ~ 3 개월이 지난 시점이 되었을 때, 저와 개발자 한 명만이 코드 리뷰 절차를 수행하게 되었습니다. 물론 한 방향으로만 진행되고 있었습니다. "개발자 -> 저" 이 방향은 제가 코드 리뷰를 꼼꼼히 보았지만 "저 -> 개발자" 로 전달된 리뷰 요청에 대해서는 그냥 보는 시늉만 내고 있었습니다. 제가 보낸 코드 리뷰 요청에 새로운 의견을 제시하거나 문제점을 찾아내는 경우가 거의 없었으니까요. 물론 이 개발자에게 코드 리뷰는 어떻게 하는 것이라는 등에 대해 알려 주지 않은 것도 이런 상황을 만든 주요 이유 중의 하나라고 생각합니다.
그래도 소득이라면 이슈 기반으로 개발이 진행되고 코드 리뷰 요청은 하고 있으니 어느 정도 개선은 되고 있다고 생각했습니다. 그래서 최소한 이 부분만이라도 다른 개발자에게 조금씩 전파하려고 했습니다. 물론 이 시점에 전체 공지를 하고
"지금부터는 이런 방식으로 개발을 하려고 하니 모두 이 절차를 준수해주세요."
라고 할 수도 있겠지만 이런 방법으로는 개발팀에 적용하기 어렵다는 것을 경험으로 알고 있었기 때문에 이렇게 하기는 싫었습니다. 코드 리뷰, 이슈 기반 개발 등이 남을 위해서 하는 것이 아니라 서비스를 개발하는데 나에게 도움이 된다는 것을 스스로 알고 스스로 참여하도록 만들고 싶었습니다.
그래서 다른 한국 개발자가 이끌고 있는 작은 단위의 개발 조직에(전체 3명) 적용해보자고 했습니다. 코드 리뷰까지는 아니더라도 이슈 기반으로 개발하고 브랜치를 관리하면서 Pull Request를 보내는 프로세스 정도만 적용해보았습니다. 여기서 코드 리뷰를 적용하지 않은 것은 제가 코드 리뷰를 봐줄만한 여유가 없었고, 이 팀 스스로도 코드 리뷰를 할 수 있는 수준이 아니라고 판단해서 입니다.
이렇게 하면서 다른 개발 조직 중 한명에게는 코드 리뷰 프로세스를 추가하도록 했습니다. 코드 리뷰 요청은 저에게로 하고 모든 요청에 대해서 코드 리뷰를 거치고 제가 merge 하는 프로세스 였습니다. 이렇게 특정 개발자와 한명과 진행하게 된 것은 이 개발자가 원격 근무를 해야 하는 특수한 상황이라 원격 개발 근무를 위해서는 이런 과정이 필수라고 생각했습니다. 이 개발자도 이런 상황을 이해하고 적극적으로 프로세스에 참여 하였습니다. 그 다음은 이 개발자가 참여하고 있는 서비스의 다른 개발자를 참여 시켰습니다. 이것은 기존에 저와 같이 코드 리뷰를 진행하고 있던 개발자에게 요청하였고 이 개발자가 다른 개발자들에게 설명하고 참여를 시켰습니다.
이렇게 전체를 한번에 적용하기 보다 개발자 개인의 상황, 개발 팀의 상황 등에 맞추어 더디지만 조금씩 진행하였습니다. 현재는 몇 개의 개발팀을 제외한 다수 개발팀에서 어설프지만 이슈 기반, 코드 리뷰를 진행하고 있는 상황입니다.
코드 리뷰를 기반으로 한 전체 프로세스 개선
이제 만족할 수준은 아니지만 그래도 여기 저기에서 삐걱거리면서 돌아가는 모습이 보이기는 합니다. 이제 전체 프로세스를 개선할 수준은 되는 것 같아 여러 조직으로 코드 리뷰 요청을 저에게 하도록 하였습니다. 그러면서 코드 리뷰를 위해 다음 방식으로 해달라고 했습니다.
- 코드 리뷰를 위해 Git Web UI 에서 Pull Request를 보내주세요.
- 원본 레포지토리에 작업 브랜치를 만들지 말고 Fork 한 개인 레포지토리를 만들어 주세요.
- 개인 레포지토리에 브랜치를 만들고 이 브랜치로부터 원본 레포지토리의 master로 Pull Request를 보내주세요.
- 모든 Pull Request는 이슈 기반으로 생성해 주세요.
- Commit 로그에는 반드시 이슈 번호를 넣어 주세요.
- 이 요청 사항에는 개발 진행전에 이슈를 등록하고 개발을 진행해달라는 의미가 내표되어 있음
- 코드 리뷰에 작성된 의견이 모두 해결되기 전에는 merge가 안됩니다.
- 코드 리뷰에 대해 이견이 있으면 이견을 추가하고 토론할 수 있습니다.
- 코드 리뷰어의 내용이 반드시 옳은 것은 아닙니다.
- 코드 리뷰어가 작성한 내용은 지시가 아닌 의견입니다.
- 리뷰에 등록된 모든 사항에 대해 확인이 되어야 Merge가 됩니다.
개발 전체 프로세스를 만들려고 하기 보다 단순히 코드 리뷰를 위해서는 이렇게 해달라고 주문한 것입니다. 하지만 위 내용을 보면 개발의 핵심 프로세스가 많이 들어가 있습니다. 즉 별도의 개발 프로세스를 정의하지 않았지만 하나의 목적(코드 리뷰)을 위해 자연스럽게 녹아 들게 하였습니다.
Slack 으로 통합
코드 리뷰를 원할하게 수행하기 위해서는 Pull Request 요청 사항에 대한 확인, 리뷰어가 코멘트를 추가했을 때 알람을 받을 수 있는 구성이 필요하게 되었습니다. 이를 위해 선택한 것이 Slack 이었습니다. 중국에서 Slack을 사용하는 것은 쉽지는 않습니다. 처음 로그인 시 접속이 느리고, 로그인이 되어도 가끔씩 연결이 끊기는 등의 문제가 있습니다. 그래서 현재 수순에서는 특별하게 추가 작업 없이 가장 쉬운 통합 방법이라 Slack을 선택하였습니다.
NHN엔터에서 서비스하고 있는 두레이 서비스의 메신저를 사용해보려고 했지만 저희가 사용하고 있는 Git Web UI 도구인 Gogs와 연결을 위해서는 추가 작업이 필요해서 현재는 Slack으로 통합하였습니다. 사용자가 많아지고 개발팀에 여유가 조금 생기면 두레이 메신저와 연결할 예정입니다.
스스로 생각해서 개선하기
여기까지 진행된 상태에서도 여전히 이슈 중심으로 관리하는 것은 강제하지 않고 있었습니다. 저는 대부분의 Slack 메시지를 확인하고 있는데(코드 리뷰 요청을 놓치지 않으려고), Slack에서 올라오는 메시지를 보는 중 한가지 특이한 메시지가 보여 확인해 보았습니다. 메시지의 내용은 새로 이슈가 등록되었다는 메시지인데 등록자를 보니 개발자가 아닌 테스트 팀에서 등록한 것이었습니다.
테스트 팀에게는 제가 이슈나 개발 프로세스 관련해서 어떤 가이드나 멘트를 하지 않았음에도 테스트 팀에서 테스트 수행하면서 발생한 버그를 이슈 관리 시스템의 이슈로 등록하고 이것을 개발자가 받아서 해결하는 방식으로 진행하고 있었던 것이었습니다.
이런 프로세스는 테스트 또는 테스트 담당자가 있는 조직에서는 일반적으로 진행하고 있는 방식인데 특별한 가이드도 하지 않았는데 스스로 프로세스를 진화해 나가고 있었던 것이었습니다. 물론 이것 역시 전체 개발팀이 아닌 일부 테스트 담당자와 일부 개발팀에서만 진행되고 있었습니다. 이것을 보면서 조금씩 더디지만 스스로 진화를 하고 있다는 생각에 조금은 안도가 되기도 했습니다.
최근에는 어느 개발팀으로부터 브랜치 관리에 대한 질문을 받았습니다. 브랜치 관리에 대해서 어떻게 적용하면 좋을까 하는 생각은 계속 하고 있는 중이었습니다. 브랜치 관리가 적용되면 배포 단계에서 한 단계 작업이 더 발생할 수 있어서 번거롭게 생각하지 않을까 하는 우려가 있었기 때문입니다. 이런 우려를 말끔하게 날려버리는 질문이었습니다. 이슈 등록, Pull Request & Merge 형태로 진행하다 보니 자연스럽게 Test, Staging, Production에 대한 코드의 스냅샷이 다르다는 것을 알게 된 것입니다. 이 경우 Upstream에 대한 브랜치 관리가 필요하게 되는데 바로 그 질문은 개발팀에서 던진 것입니다.
자동화된 Release Note 공지까지
테스트 팀이 스스로 프로세스를 개선하고 있는 상황을 보면서 테스트 팀에게 다음과 같은 내용을 추가로 부탁했습니다.
배포 시 기존 배포된 Tag와 현재 배포되는 Tag의 Commit 로그 Diff 정보를 이용하여 Slack의 "release_production" 채널로 자동으로 보내 주세요.
마이크로 서비스 구성에서 어떤 서비스의 어떤 기능이 언제 배포되는지 거의 알지못했습니다. 심한 경우에는 특정 모듈이 배포된 이후에 이 기능과 연결되어 있는 다른 서비스에서 문제가 발생하는 경우가 종종 있었습니다. 문제가 발생해도 문제의 원인이 새로 배포된 서비스에 있다는 것도 파악하기 어려웠습니다. 배포된 사실 조차 알지 못했기 때문입니다. 물론 테스트 코드가 잘되어 있고 서비스간 통합 테스트 환경이 잘되어 있으면 좋겠지만 아직 이렇게 배부른 환경이 아니기 때문에 작은 노력으로 릴리즈 노트를 공유하는 것만으로도 도움이 될 것이라 생각했습니다.
어떻게 진정한 Peer 리뷰를 만들어 나갈까?
지금까지 글의 내용을 보시면 개발팀에 아직까지 제대로 된 코드 리뷰 문화가 생겼다고 할 수는 없는 상황이라는 것을 아실겁니다. 맞습니다. 현재 수준에서는 저 혼자만 리뷰어가 나머지는 리뷰에 참여하지 않는 한방향 리뷰 입니다. 이런 상황에서는 다른 개발자가 어떻게 코드를 만들고 있는지, 해당 모듈이 어떤 로직으로 구성되어 있는지를 파악하기 어려운 실정입니다. 개발자 상호간에 Peer 리뷰 문화를 만들어 나가야 하는데 이 부분 앞으로 고민해야 할 부분입니다.
특별한 대안이 있는 것은 아니고 다음 방식으로 진행해보려고 합니다.
- 개발팀 중 한두명 정도에게 다른 개발자의 PR 중 일부에 대한 코드 리뷰를 할당한다.
- 최종적으로 필자가 한번 더 확인
- 이를 점차 확산
마치며
개발팀의 문화를 만들어 나가는 것은 아주 어려운 일이라는 것을 잘 알고 있습니다. 그리고 각 개발팀의 환경이 다르기 때문에 정답도 없습니다. 그저 조금씩 꾸준히 개선해나가려는 활동을 한다는 것 자체만으로 좋은 문화를 가졌다라고 말할 수 있지 않을까요? 욕심이지만 내년 상반기가 끝나는 시점에는 좋은 개발 프로세스와 문화가 갖추어져 있기를 기대해봅니다.
다음 글에서는 제가 주로 하고 있는 코드 리뷰 활동에 대해 사례와 함께 공유하도록 하겠습니다.