주요 컨텐츠로 건너 뛰기

오픈소스 멘토링으로 react-spectrum 기여하기

발행 시간 오후 10:36

지난 9월, GDG 송도의 인제님이 리드하시는 오픈소스 멘토링 6기에 참여했습니다. 오랜 시간 동안 오픈소스 기여 하고 싶다, 하고 싶다 말만 하고 혼자서는 엄두가 나지 않아서 막상 실천하지 못했었는데요. 오픈소스 멘토링으로 4일 만에 adobe의 오픈소스 프로젝트인 react-spectrum에 PR까지 올릴 수 있었습니다. 저는 그동안 오픈소스 프로젝트를 많이 살펴 본 적도 없어서 사실 멘토링 기간 안에 PR을 올릴 수 있을까 반신반의했는데요. 리드님이 잘 이끌어주신 덕분에 오픈소스 기여를 위한 첫 발걸음을 뗄 수 있었습니다. 멘토링에서 익힌 방법으로 앞으로는 혼자서도 오픈소스 기여를 할 수 있겠다는 자신감도 얻을 수 있었어요. 오픈소스 기여를 시작하고 싶은 분들께 힌트를 드릴 수 있을까 해서 4일간 오픈소스 멘토링에 참여한 기록을 남깁니다.

Table of contents

Open Table of contents

이슈를 잘 선정하는 팁 익히기

첫 날, 리드님이 오픈소스 기여 가이드를 공유해주셨는데요. 이 글을 읽고 기여해보고 싶은 오픈소스를 고르면 리드님이 도전해볼만한 이슈를 추천해주셨습니다.

이슈를 잘 선정하는 방법은 가이드에 잘 설명되어 있는데요. 키포인트를 꼽자면, 처음 오픈소스에 기여할 때는 이슈를 잘 선정하는 것이 가장 중요합니다. 2시간 안에 해결할 수 있는 이슈를 선정하는 것을 목표로 이슈에 재현 방법이 명확히 나와있거나 메인테이너가 어느 정도 해결할 수 있는 방법을 적어둔 이슈를 고르는 것이 좋습니다. good first issuecontribution welcome 과 같은 라벨이 붙은 이슈를 선택하는 것도 방법입니다.

일단 그런 이슈를 찾으려면 메인테이너가 이슈를 활발히 확인하는 오픈소스를 고르는 게 좋습니다. 가이드를 보기 전까지는 업무에서 사용하는 swr, react-hook-form, radix-ui에 기여하고 싶다고 생각했었는데요. 이 프로젝트들은 메인테이너가 이슈를 활발하게 확인하는 느낌은 아니라 메인테이너가 라벨링을 활발하게 해주는 vite, react-spectrum 프로젝트를 선택했습니다.

오픈소스 이슈 선정하고 리드와 함께 논의하기

다음 날, 리드님이 이 두 오픈소스를 살펴보신 뒤 메인테이너가 간단히 확인해준 이슈, 재현 방법이 나와있는 이슈, 상세한 설명이 적힌 이슈 3개를 추천해주셨습니다. (퇴근 후에 레포 다 일일이 확인하시고 이슈를 추천해주시는 리드님의 열정에 감탄했습니다)

셋째 날, 리드님이 추천해주신 이슈를 참고해서 기여하고 싶은 이슈 2~3개를 찾아 올렸습니다. 생각보다 이 과정이 가장 어려웠던 것 같아요. vite은 프론트엔드 툴이긴 하지만 번들러라 평소에 다루는 코드랑은 많이 다르게 느껴졌어요. vite의 동작방식을 이해하기 위해서 컨퍼런스 영상을 보기도 했습니다. react-spectrum은 보다 보니 오픈소스 초보자 친화적인 프로젝트라는 걸 느낄 수 있었는데요. 초보자가 해결할 수 있을 법한 이슈는 이미 이 이슈를 가져가겠다는 코멘트가 많이 달려 있더라고요. 이런 이슈에 PR을 올리는 게 실례인지 고민이 되었는데요. 코멘트가 달려 있어도 오랜 기간 PR이 올라오지 않았다면 가져가도 괜찮다고 하네요.

리드와 함께 이슈 해결 방법을 조사한 후 공유하기

저는 vite에서 리드님이 추천해주신 이슈 1개, react-spectrum의 이슈 3개를 찾아서 올렸습니다. 리드님은 vite의 이슈 1개, react-spectrum의 이슈 1개를 해결해보면 좋겠다고 피드백 주셨어요. 특히 vite의 이슈는 리드님께서 직접 코드를 확인한 후 짐작가는 이슈 지점이 어디인지 알려주기도 하셨어요. 리드님의 조언을 읽기 전에는 사실 이 이슈를 어떻게 해결해야할지 잘 감이 안왔는데요. 메인테이너가 코멘트를 남겨놓긴 했지만 영어로 되어 있다 보니 무슨 말인지 잘 이해가 안되더라고요. 리드님께서 실제 코드를 짚어주면서 설명해주시니 어렴풋하게 어디서부터 접근하면 좋을지 감을 잡을 수 있었습니다.

오프라인으로 만나 함께 PR 만들기

일요일 2시, 리드님과 7명의 멘티가 함께 오프라인 모임을 가졌습니다. 사실 모임을 가기 전 디버깅을 해보고 갔어야 했는데 저는 디버깅을 못해봤어요. 오프라인 모임에서 모두가 PR을 올리는 게 목표였는데 저만 PR을 못 올릴 것 같다는 두려움에 떨며 모임을 나갔는데요. 각자 어떤 이슈를 선정했는지 공유한 다음, 5시까지 디버깅해서 PR을 올리기로 했습니다.

react-spectrum의 parseDuration

제가 선택한 이슈는 react-spectrum 프로젝트의 parseDuration 관련 이슈였습니다. 어떤 이슈인지 설명하자면, react-spectrum에는 parseDuration("PT36H") 와 같이 특정한 규칙을 가진 duration string을 인자로 넣어 호출하면 아래와 같이 시간 관련 property가 담긴 객체를 반환하는 parseDuration 함수가 있습니다.

{
  "years": 0,
  "months": 0,
  "weeks": 0,
  "days": 0,
  "hours": 36,
  "minutes": 0,
  "seconds": 0
}

ISO 8601에서는 PT36H 가 유효한 duration string이기 때문에 위와 같이 hours property가 36인 객체가 정상적으로 반환되어야 하는데, 현재는 Error: Invalid ISO 8601 Duration string: PT36H 와 같은 에러가 뜬다는 문제제기였습니다. 이슈를 제기한 사람이 hours를 24 미만의 값만 넣을 수 있도록 제한하는 것이 문제 같다고 짚고 있고, 메인테이너도 Temporal.Duration 스펙을 따라야한다는 코멘트를 남겨놓은 아주 친절하게 설명되어 있는 이슈였습니다. 리드님은 Temporal.Duration 스펙을 확인해서 이 스펙과 구현만 맞춰주면 될 것 같다고 피드백 주셨습니다.

먼저, 오픈소스 레포를 fork를 합니다. Temporal.Duration 문서를 확인했을 때, hours에 들어갈 수 있는 값에는 제한이 없어보였고, 실제로 Temporal.Duration.from("PT36H") 를 실행해봤을 때 문제 없이 hours property의 값이 36으로 출력되었습니다. 그럼 hours의 max 값을 23으로 제한할 필요가 없기 때문에 max를 Infinity로 수정했습니다.

그러고 나서 제대로 동작하는지 확인하기 위해서 로컬 빌드해 실행해보았는데요. 오픈소스 프로젝트 중에서는 로컬에서 빌드해볼 수 없는 프로젝트가 많다고 합니다. 하지만 다행히 react-spectrum은 바로 빌드에 성공했어요. 하지만 수정했음에도 여전히 에러가 뜨고 있었는데요. 디버깅 해보니 기존에 작성되어 있던 유닛 테스트 코드에 hours가 23이 넘는 duration string이 인자로 들어왔을 때, 에러를 출력하게끔 되어 있어서 에러가 뜨는 것이었습니다. 이 부분도 에러가 뜨지 않고 정상적으로 객체를 반환하도록 수정해주었습니다. 테스트를 수정한 김에 PT36H string에 대한 유닛 테스트를 추가해주었습니다.

Temporal.Duration 스펙을 확인했을 때, hours 뿐만 아니라 years, months 등 다른 property에도 최대값 제한이 없다는 것을 확인할 수 있었는데요. 이 값에 대해서도 수정해서 PR을 올리는 것이 좋을지 리드님께 여쭤봤는데 일단 이슈가 올라온 부분에 대해서만 수정 PR을 올리고 이 PR이 머지된 이후에 추가적으로 PR을 올려 수정하는 것이 좋다는 답변을 얻었습니다.

PR을 올릴 때, 본문에 Closes #{이슈번호} 를 포함하면 해당 PR과 이슈를 연결할 수 있습니다. 리드님의 피드백을 받아 Temporal.Duration 스펙을 확인했다는 설명과 이 PR이 머지된 다음에는 years, months 등 다른 property에도 최대값 제한을 없애야할 것 같다는 추가 설명을 덧붙였습니다.

PR을 올리면 github actions가 도는데요. 신기했던 것 중 하나는 Adobe Contributor License Agreement(CLA)에 서명했는지 여부를 체크하는 것이었습니다. 이 부분에서 통과가 안되어서 조금 헤맸었는데 지금은 시간이 조금 지나 정확히 기억나지 않는데 이 페이지에서 서명한 다음 커밋을 수정해서 올려서 github actions을 다시 돌렸더니 통과 됐던 것 같습니다.

그렇게 우여곡절 끝에 올린 PR은 이 링크에서 확인할 수 있습니다. 사실 머지가 된 다음에 글을 올리고 싶었는데요. 아쉽게도 아직 머지가 되지 않았습니다. 메인테이너가 남긴 코멘트에 따르면 ISO8601에서는 최대값 제한이 있고 Temporal.Duration에는 최대값 제한이 없는 사양 불일치가 있다고 하네요. 일단 한 명의 메인테이너에게서 approve를 받았지만 팀 내부의 확인을 거쳐 추후에 머지가 될 것 같습니다.

멘토링에 참여한 후기

오픈소스에 기여해보고 싶다고 생각한 건 2년 전 쯤이었는데요. 번역 프로젝트부터 깔짝여봤지만 기술 이슈를 해결하는 것은 막막하게 느껴지더라고요. 멘토링이 아니었다면 혼자서 이슈 선정하기도 어려웠을 것 같고, PR 작성하는 것도 감을 잡기 어려워 포기했을 것 같아요. 멘토링으로 오픈소스 시작할 수 있어서 너무 행운이었다는 생각이 들었습니다. 그래서 저와 같이 오픈소스 기여를 해보고 싶지만 어려움을 겪고 계신 분께 오픈소스 멘토링을 꼭 추천하고 싶어요.

아직 유닛 테스트 코드를 작성해본 적이 없는데 이미 잘 작성된 유닛 테스트 코드를 보면서 찍먹해볼 수 있어서 좋았고, Temporal.Duration 스펙도 알게 되어서 더 의미있는 시간이 되었습니다. 리드님이 추천해주신 vite 이슈도 혼자 해결해보고 싶고, 앞으로도 꾸준히 오픈소스 기여를 하는 습관을 들이고 싶습니다.