1. 개요
사내 프로젝트를 진행하면서 React Native 앱을 개발하게 되었는데, 앱이 점점 덩치가 커지더니 코드 라인 수가 몇만 라인을 돌파할 즈음 CI/CD 프로세스 없이는 도저히 프로젝트 진행이 불가능하다고 느껴졌다. -(너무 늦게 도입했다는 생각이..)-
예를 들자면 다음의 경우에 개발자의 Context Switching이 많이 일어나고 개발자의 생산성이 떨어지는 문제가 있었다.
클라이언트가 '중간 배포 버전을 보고 싶다' 라고 하면 중간 배포 버전을 만들기 위해 Production Build를 하고, 배포 서버에 APK를 올리거나 TestFlight에 업로드 해야할 경우 코딩을 진행할 수 없음.
라이브러리가 업데이트 되었을 때 build가 깨질 경우 어느 라이브러리가 문제인지 디버그해야 함.
코드를 수정했는데, 메인 페이지가 rendering이 제대로 되지 않을 경우 앱 내로 진입할 수 없음. 디버그해야 함.
최종 수정 버전을 Android Play Store, IOS APP Store에 업로드 해야하는 경우, 코딩을 할 수 없음.
Reat Native의 경우 IOS, Android Project가 각각 나오기 때문에, 테스트를 따로 진행해야 함.
위의 문제들은 모두 CI(Continuous Integration), CD(Continuous Deploy) Process를 잘 정립하면 해결되는 문제라고 판단하고 다음의 Flow를 설계해보았다.
2. What to Make
따라서 결론적으로 만들고 싶은 프로세스는 다음과 같았다.
개발자가 각 용도에 맞는 branch에 코드를 커밋한다
Github은 web hook을 이용하여 CI/CD Tool에 이를 알린다.
CI/CD 툴은 Android, IOS를 각각 테스트하며 테스트 배포앱을 결과물로 제공한다
Slack에는 테스트 결과, 테스트 배포 앱 링크를 제공한다.
이러한 flow에 알맞는 CI / CD, Automation 기술 스택들을 선정하기 위해 여러 가지 후보군을 선정해 보았다.
3. Jenkins Vs Travis Vs CircleCI
초창기에는 이전에 사용해 보았던 Jenkins를 고려하였으나 자체 보유하고 있는 서버에 올리거나 클라우드에 올려야 하기 때문에 서버 관리 비용인 돈과 시간이 필요하고 Jenkins의 복잡한 Configuration 때문에 생기는 높은 Learning Curved가 필요하며 결정적인 이유로 MacOS에서 Xcode Build를 해야하기 때문에 MacOS가 필요하는 등 여러가지 이유로 선택지에서 제외하였다.
그다음 선택지는 Travis 였는데 CircleCI 와 많은 고민을 거쳤다. 사실 두 가지 모두 성숙한 서비스이기 때문에 무엇을 선택해도 크게 다르지 않다는 생각을 가지고 있었다. 따라서 이미 사용해봤던 Travis를 도입하려던 찰나 FaceBook의 React Native 프로젝트인 facebook/react-native 는 어떤 CI Tool을 사용하고 있나 궁금해졌다. 확인해 본 결과 FaceBook이 사용하고 있는 Tool은 CircleCI 였다.
그렇다면 왜 CircleCI를 사용했을까? React Naitve의 프로젝트 커밋 히스토리를 찾아보니 이전에는 Travis와 CircleCI를 둘다 사용했었고, 점차 Travis -> CircleCI로 Migration하는 커밋들이 늘어났다. 이유는 빌드 속도 때문으로 보인다.
CI Tool들은 직접 컨택을 하지 않는 이상 과금이 총 빌드 시간과 관련이 있다. 따라서 빌드시간이 적으면 적을수록 과금 정책이 싼 plan을 선택할 수 있기 때문에 빌드 속도, 시간은 무척 중요하다. -물론 개발자가 오랜 빌드를 기다리기 싫은 이유도 있고-
관련 커밋: Migrate Travis over to Circle by grabbou · Pull Request #16354 · facebook/react-native · GitHub
4. CI/CD Tool 로서의 선택: CircleCI
따라서 우리도 React Native의 프로젝트처럼 과거의 문제를 답습하지 않기 위하여 히스토리를 뒤져보다가 CircieCI를 선택하였고 2.0 Docs - CircleCI부터 차례대로 진행하였다. 프로젝트를 진행하였을 때는 MacOS가 CircleCI 1.0만 가능했었는데 2018년 1월부터 CircleCI 2.0도 지원하기 때문에 아티클을 쓰는 겸사겸사 아래에서 1.0 -> 2.0 Migration을 진행해보기로 한다.
5. Fastlane Vs Appium VS Bitrise
사실 세 가지 툴들은 동일한 카테고리에 있는 경쟁대상은 아니다.
Fastlane은 App Automation Tool을 담당하는 오픈소스이고 무료
Appium은 App Test의 목적으로 사용은 오픈소스이며 무료
Bitrise은 CI/CD Tool 서비스이며 유료
우리가 만들려고 하는 CI/CD Architecture에서 위의 3가지 툴들에게 기대하는 근본적인 역할은 다음 세 가지다.
기능이 풍부하고 쉬우며 관리를 줄일 수 있는 좋은 툴이라면 얼마든지 비용을 지급할 수 있다. 다만 많은 기능을 쓰지 않는다면 스타트업은 비싼 플랜이나, 정기적인 과금을 지출하기에는 까다로움이 있다. 따라서 웬만하면 무료여야 한다. -> Fastlane, Appium
CI 위에서 테스트와 배포에 도움을 주어야 한다. -> Fastlane, Appium, Bitrise(자체 CI Tool)
생태계가 성숙 돼 있고 건강하며, 활성화가 아직도 진행 중어야 한다. 이는 곧 레퍼런스가 풍부함을 의미한다. -> Fastlane (Star 수가 가장 많고, 검색결과가 많음)
세가지 모두가 비교대상인 대체재 라기보다는, 어느정도의 역할을 상대방이 보완해 줄 수 있는 보완재의 성격을 가지고 있다. Bitrise 같은 경우에는 Fastlane 과 궁합이 좋다는 외국 커뮤니티의 글이나 fastlane 진영에 글들이 많아서 잠깐 고려하기도 했으나 CircleCI가 Bitrise를 대체할 수 있으니, 이미 CircleCI를 선택하려고 마음을 먹었다면 1,2,3번의 조건을 모두 만족하는 Fastlane 진영으로 마음을 굳혔다.
Britise는 Mobile을 타겟으로 나온 서비스이기 때문에 CircleCI 보다는 목적이 더 명확하다고 할 수 있다. 하지만 우리 팀은 앱만 만드는 것이 아니기 때문에 보다 범용적인 CI Tool인 CircleCI, Fastlane를 선택하지만 Mobile first 전략을 취하고 있는 스타트업이라면 Bitrise도 충분히 고려할 만하다.
6. Automation Tool 로서의 선택: Fastlane
fastlane이란 툴은 Application의 Automation에 필요한 기능을 담고 있는 툴이다. 예를 들자면, $ fastlane beta 라는 명령어를 친면
Build Number를 증가시키고 앱을 빌드하고 TestFlight에 업로드하고 Slack에 메시지를 보낸다.
이런 일련의 과정들을 간단한 CLI 명령어 한줄로 대신 수행해주며 아래와 같은 간단한 ruby 문법으로 행동을 정의할 수 있다.
lane :beta do increment_build_number build_app upload_to_testflight slack end