뒤로가기
오픈소스에 처음 기여했을 때

June 29, 2023

careerlearning

오픈소스에 기여하고 싶다는 생각은 오래전부터 있었다. GitHub 프로필에 초록색 잔디만 사이드 프로젝트로 채우는 것보다, 실제로 사람들이 쓰는 프로젝트에 무언가를 보태고 싶었다. "오픈소스 기여자"라는 타이틀이 개발자로서 멋있어 보이기도 했고.

하지만 실행으로 옮기기까지 1년이 넘게 걸렸다. 이유는 단순했다. 무서웠다.

이슈 탭을 열고 닫기를 반복한 3개월#

처음에는 매일 쓰는 라이브러리의 GitHub 저장소를 구경하는 것부터 시작했다. 코드를 읽어보고, 이슈 탭을 열어보고, PR을 구경했다. 이슈에 달린 토론을 읽으면서 "나도 저 정도는 할 수 있을 것 같은데"라는 생각과 "저 사람들 대화 수준을 보면 나는 아직 멀었다"라는 생각이 번갈아 들었다.

good first issue 라벨이 붙은 이슈를 찾아봤다. 초보자도 할 수 있는 쉬운 이슈라고 들었는데, 막상 열어보면 쉽지 않았다. "문서에서 이 부분의 예제를 추가해주세요" 같은 건 그나마 접근 가능해 보였는데, 이미 다른 사람이 "제가 하겠습니다"라고 코멘트를 달아놓은 경우가 대부분이었다. 인기 있는 프로젝트일수록 경쟁이 심했다.

코드 관련 이슈는 더 어려웠다. "이 함수에서 엣지 케이스 처리가 빠져 있습니다" 같은 이슈를 보면, 일단 그 함수가 어디에 있는지 찾는 것부터 막막했다. 프로젝트 구조를 이해해야 하고, 빌드 환경을 세팅해야 하고, 테스트를 돌려봐야 한다. "good first issue"라는 라벨이 무색하게, 프로젝트에 진입하는 것 자체가 큰 허들이었다.

3개월 동안 이슈 탭을 열고, 읽고, "나중에 해야지" 하고 닫기를 반복했다.

버그를 발견하다#

전환점은 의외로 일상에서 왔다. 회사 프로젝트에서 날짜 처리 라이브러리를 쓰고 있었는데, 특정 타임존에서 날짜가 하루 밀리는 버그를 발견했다. 처음에는 내 코드의 문제인 줄 알고 한참을 디버깅했다. 그런데 아무리 봐도 내 코드는 맞았고, 라이브러리 쪽의 타임존 변환 로직에서 문제가 발생하고 있었다.

라이브러리 코드를 까봤다. UTC 오프셋을 계산하는 부분에서 서머타임(DST) 전환 시점을 고려하지 않는 케이스가 있었다. 한국에서는 서머타임이 없어서 대부분의 한국 개발자가 겪지 않는 버그였는데, 우리 서비스가 유럽 타임존도 지원해야 해서 발견된 거였다.

이걸 이슈로 올릴까 말까 고민했다. "내가 잘못 읽은 거면 어쩌지?" "이미 알려진 이슈일 수도 있는데, 중복 이슈를 올리면 민폐 아닌가?" 이런 걱정이 한가득이었다.

기존 이슈를 전부 검색해봤다. 비슷한 이슈가 없었다. 그래서 용기를 내서 이슈를 작성했다.

이슈 하나 쓰는 데 2시간#

이슈를 쓰는 데 2시간이 걸렸다. 진짜 2시간이다.

제목을 뭐라고 할지부터 고민이었다. 영어로 써야 하는데, "bug"라고 하면 너무 단정적인 것 같고, "unexpected behavior"라고 하면 너무 모호한 것 같고. 결국 "Incorrect date conversion when crossing DST boundary" 정도로 정했다.

본문은 더 어려웠다. 재현 단계를 명확하게 적어야 했다. 어떤 입력값으로, 어떤 타임존에서, 어떤 결과가 나왔고, 기대하는 결과는 뭔지. 이걸 영어로, 그것도 전 세계 누가 봐도 이해할 수 있게 써야 했다. 코드 예제를 만들고, 스크린샷을 찍고, 라이브러리 버전과 Node 버전을 적었다.

제출 버튼을 누르기 전에 세 번이나 다시 읽었다. 오탈자는 없는지, 혹시 오해를 살 만한 표현은 없는지, 너무 당연한 걸 물어보는 건 아닌지. 손이 떨렸다고 하면 과장이지만, 심장은 확실히 빨라졌다.

버튼을 눌렀다.

메인테이너의 답변#

30분 만에 답변이 왔다. 프로젝트의 메인테이너 중 한 명이었다.

"Great catch! This is indeed a bug in our timezone offset calculation. The DST transition edge case was missed. Would you be interested in submitting a fix?"

솔직히 놀랐다. 두 가지 측면에서.

첫째, 답변이 빠르고 친절했다. 무시당하거나, "이미 알고 있습니다" 같은 차가운 답변을 예상했는데, 오히려 칭찬을 해줬다. "Great catch"이라니. 내가 2시간 동안 고민하며 쓴 이슈를 가치 있는 것으로 인정해준 느낌이었다.

둘째, 직접 고쳐보겠냐고 물어봤다. 이건 예상 못했다. 보통 메인테이너가 직접 고치거나, 다른 기여자에게 맡기는 줄 알았다. 나 같은 처음 온 사람에게 기회를 주는 거였다.

"I'd love to try!"라고 답했다. 타이핑하면서 "이게 진짜 되는 건가?"라고 생각했다.

PR을 만들기까지#

프로젝트를 포크하고, 클론하고, 로컬에 빌드 환경을 세팅하는 데만 한 시간이 걸렸다. Contributing 가이드를 읽었다. 코드 스타일 규칙, 커밋 메시지 컨벤션, 테스트 실행 방법. 회사 프로젝트에서는 이미 세팅된 환경에서 일하니까 이런 초기 세팅에 시간을 쏟을 일이 없는데, 새 프로젝트에 처음 뛰어드는 건 이런 과정이 필요했다.

버그를 고치는 것 자체는 생각보다 단순했다. DST 전환 시점을 체크하는 조건문 하나를 추가하는 거였다. 코드 변경은 15줄 정도. 하지만 그 15줄을 쓰기 위해 관련 코드를 200줄 넘게 읽었다. 함수의 맥락을 이해해야 정확한 위치에 정확한 수정을 넣을 수 있으니까.

테스트를 작성하는 게 더 오래 걸렸다. 코드 수정보다 테스트 코드가 세 배는 길었다. 여러 타임존, 여러 날짜에 대해 DST 전환을 검증하는 케이스를 만들었다. 기존 테스트 패턴을 참고해서 스타일을 맞췄다.

PR을 올리기 전에 Contributing 가이드를 한 번 더 읽었다. PR 설명에는 관련 이슈 번호를 링크하고, 변경 사항을 요약하고, 테스트를 어떻게 했는지 적었다. 커밋 메시지도 프로젝트 컨벤션에 맞게 수정했다.

PR 제출.

코드 리뷰라는 경험#

다음 날 코드 리뷰가 달려 있었다. 메인테이너가 직접 리뷰를 해줬다.

리뷰 코멘트는 네 개였다. 하나는 변수명 제안. "offset"보다 "utcOffset"이 더 명확하다고. 하나는 테스트 케이스 추가 요청. 남반구 타임존도 커버하면 좋겠다고. 하나는 코드 스타일. 프로젝트에서 쓰는 함수 명명 규칙에 맞추라고. 마지막 하나는 칭찬. "The test cases are thorough. Nice work."

회사에서 받는 코드 리뷰와는 분위기가 달랐다. 회사에서는 서로 알고 있는 사이라 맥락이 공유된 상태에서 리뷰가 이루어진다. 오픈소스에서는 처음 보는 사람의 코드를 리뷰하면서도 존중하는 톤을 유지해야 한다. 그리고 이 메인테이너는 그걸 잘 해줬다.

지적할 때도 "이건 틀렸다"가 아니라 "이렇게 하면 더 좋을 것 같은데 어떻게 생각해?"라는 식이었다. 강제가 아니라 제안. 나의 의견도 물어봐 줬다. "이 부분은 이런 이유로 이렇게 했는데요"라고 답하면 "아, 그런 맥락이 있었구나. 그러면 유지하자"라고 수용하기도 했다.

코멘트를 반영하고, 다시 커밋하고, 리뷰가 한 번 더 왔다. "LGTM." 그리고 머지.

GitHub에 "Merged" 라벨이 붙은 순간의 기분은, 처음 코딩을 배우고 "Hello World"를 출력했을 때랑 비슷했다. 뭔가 새로운 세계에 발을 들인 느낌.

기여하면서 배운 것들#

이 경험에서 배운 게 코드를 고치는 기술보다 훨씬 많았다.

문서화의 중요성. 이슈를 쓸 때, 재현 단계를 명확하게 적는 게 얼마나 중요한지 몸으로 느꼈다. 회사에서 버그 리포트를 올릴 때도 이전과 확연히 달라졌다. "안 돼요"가 아니라 "이런 조건에서 이렇게 하면 이런 결과가 나옵니다"로 쓰게 됐다. 이게 상대방의 시간을 엄청나게 절약해준다.

코드 품질 기준. 오픈소스 프로젝트의 코드를 읽으면서, 내 코드의 기준이 올라갔다. 변수명 하나, 함수 분리 하나에 대한 감각이 달라졌다. 전 세계 사람이 읽을 코드를 쓴다고 생각하면 자연스럽게 더 신경 쓰게 된다.

영어 커뮤니케이션. 기술 영어에 대한 두려움이 많이 줄었다. 완벽한 영어가 아니어도 된다. 명확하기만 하면 된다. 문법이 좀 어색해도 재현 단계가 정확하면 아무도 영어를 지적하지 않았다. 중요한 건 내용이지 표현이 아니었다.

글로벌 협업의 감각. 시차가 다른 사람과 비동기로 소통하는 법을 배웠다. 코멘트를 달 때 맥락을 충분히 담아야 한다는 것. 상대방이 내 코멘트를 읽을 때 나는 자고 있을 수 있으니까, 추가 질문 없이 이해할 수 있도록 써야 한다는 것. 이건 리모트 워크에서도 똑같이 적용되는 기술이다.

두 번째 기여는 훨씬 쉬웠다#

첫 기여 이후 한 달쯤 지나서, 다른 프로젝트에서 비슷한 기회가 왔다. 이번에는 공식 문서에서 오래된 예제 코드를 최신 API에 맞게 업데이트하는 작업이었다.

놀라운 건, 이번에는 무섭지 않았다는 거다. 이슈를 열고, 코멘트를 달고, PR을 보내는 흐름을 이미 한 번 경험했으니까. 문서 수정이라 코드보다 진입 장벽도 낮았다.

첫 번째가 어려운 이유는 기술적 난이도 때문이 아니다. "내가 이 프로젝트에 뭔가를 보태도 되는 사람인가?"라는 심리적 장벽 때문이다. 한 번 넘으면, 두 번째부터는 그 장벽이 확 낮아진다.

오픈소스 기여를 망설이는 사람에게#

지금 오픈소스 기여를 하고 싶은데 망설이고 있다면, 한 가지만 기억하면 좋겠다. 메인테이너들은 대부분 새로운 기여자를 환영한다. 그들도 과거에 처음 기여했던 시절이 있었고, 누군가의 도움으로 성장했다는 걸 안다. 물론 예외는 있다. 불친절한 메인테이너도 있고, 반응 없이 방치되는 프로젝트도 있다. 하지만 그건 그 프로젝트의 문제지 내 문제가 아니다. 다른 프로젝트를 찾으면 된다.

시작은 거창하지 않아도 된다. 오타 수정, 문서 개선, 에러 메시지 명확화. 이런 것들도 유의미한 기여다. 코드를 한 줄도 안 바꿔도 된다. 좋은 버그 리포트 하나가 프로젝트에 큰 도움이 되기도 한다.

나의 첫 기여는 15줄짜리 버그 수정이었다. 세상을 바꾼 건 아니다. 하지만 그 15줄이 나를 바꿨다. 코드를 쓰는 게 나 혼자만의 일이 아니라, 전 세계 개발자들과 연결된 일이라는 감각. 이건 사이드 프로젝트 열 개를 만들어도 얻기 어려운 거다.