circle CI + fastlane = honey
hybrid code는 스타트업에게 빠른 앱 출시를 가능하게 만들어주는 고마운 프레임워크임과 동시에 웹 개발 경험만으로 쉽게 앱을 만들 수 있게 해 줍니다. 하지만 배포 단계에서는 iOS와 android 각각의 배포 설정들과 출시 가이드를 따라야 하기 때문에 앱 개발보다 배포가 더 일이 될 수 있습니다. (각각의 앱 경력자가 있다면 이야기가 조금 다르겠지만... 있으면 네이티브로 개발을 했겠...) 적은 인원의 스타트업에서는 시간을 아끼기 위해 자동화는 필수이며 웹 개발은 이미 태그 한방으로 kubernetes에 배포가 되는 환경이니 앱이라고 그냥 방치하면 배포에 들어가는 시간이 너무 아까워 견딜 수가 없었기도 하고해서 자동화를 해보았습니다.
mac os의 가상화를 위해 필수입니다. gitlab이나 travis CI도 mac os를 가상 머신으로 제공을 하지만 이런저런 이유로 circle CI를 사용하기로 했습니다. (아무 생각 없이 하다 보니 완성되어서...)
android와 iOS의 배포를 쉽게 해주는 툴입니다. 대부분 로컬 PC(개발용)에서 각각 fastlane명령어를 실행해서 배포하는 것으로 알고 있습니다. 물론 저만 그랬을 수도 있습니다 ^^
앱 개발을 마쳤을 때는 일단 출시가 먼저였습니다. 개발은 수월 했으나 개발 경력 10년 동안 앱 배포는 처음이어서... 웹에 대한 배포 자동화는 익숙하기 때문에 android를 먼저 자동화했습니다. mac os docker 이미지가 없는 줄만 알았기 때문이죠. 앱 배포할 때가 되면 돌아버릴 것 같았습니다. 이게 과연 자동화를 왜 했나 한 게 맞나 라는 자괴감과 mac 미니를 사서 빌드 서버로 써야 하나 어째야 하나 이걸 정말 나만 고민했을까 이래 저래 잠이 오질 않았었죠. 구성은 했지만 슬랙에 다운로드 링크만 온다 뿐이지 손수 aab파일을 다운로드하여 플레이 스토어에 등록을 하고 앱 스토어 배포를 위해 다시 배포용 폴더에서 다시 xcode를 실행해 archive 한 다음 distribution 하고... 그 이유이자 가장 큰 고민은 env 파일을 production용으로 주입해야 하는데 jenkins부터 cloud build까지 CI/CD에서 주입하던 저는 이걸 shell script를 만들어야 하나 어째야 하나 마땅한 방법이 생각나지를 않았습니다. 그래서 productin env를 포함하는 iOS용 빌드 폴더를 따로 만들어 최신 master pull 한 다음 버전과 빌드 넘버를 수정한 후... $%#$%@%@#@
android gradle plugin에 플레이 스토어에 업로드되는 것이 있는 것을 알았습니다. 바로 업로드를 자동화하자마자 fastlane이라는 것이 있다는 것을 알게 되었습니다..... 지금 보니 정말 바보 같은 2차 구성입니다. fastlane을 알았는데 굳이 android를 왜 따로... 아무튼 스토어에 업로드하는 부분의 사람의 개입을 없앴지만 여전히 iOS에 대한 production env 파일 주입이 해결되지 않았습니다. 여전히 폴더를 옮겨가며 master를 pull 받고... @#$#@%@#%! 시간이 지났지만 그림으로만 봐도 너무 거슬려서 미쳐버릴 거 같군요!!
드디어 (찾아보지도 않았으면서) circle CI에 mac os 이미지가 있다는 것을 알게 되었습니다! 자동화에 돈을 아끼지 않습니다 바로 3만 원을 결제합니다. (mac os 이미지는 유료 플랜에서만 지원됩니다. 내 시간이 3만 원보다 가취 있기를...) 이렇게 되면 아주 간단해집니다. web배포와 다를게 없어지니까요. 개발용 apk 빌드는 cloudbuild에 그대로 남겨놓고 gradle build부분만 fastlane으로 변경했습니다. circle CI로 전체 통합을 할 수 도 있겠지만 유료 결제에 credit 차감 형식이라 나름 아껴봤습니다. (사실 앱이 열개가 넘어가지 않는다면 충분한 credit인 것 같습니다.. 아아 굳이 또 안 해도 될 일을...) circle CI는 workflow를 지원하기 때문에 react native에 fit 하다고 생각됩니다. javascript 부분에서 unit testing과 linting 등을 하고 android, iOS로 각각 빌드, 배포할 수 있기 때문입니다. yarn version 커맨드를 이용해 버전을 올리고 fastlane에 있는 load_json으로 package.json을 읽어와 package.json 버전 기준으로 android와 iOS의 버전을 맞춰줍니다. 또 한 fastlane에서 자동으로 build number(version code)를 올려 주기 때문에 빌드와 배포가 전부 성공하면 repository를 push 해 줍니다. 플로우를 정리해보면
1. 배포 versioning -> yarn version
2. circle CI workflow trigger
3. javascript verify (lining, testing,...)
4. iOS, android 각각 build, archive -> fastlane
5. 변경 사항 repository commit & push
6. 슬랙 알림
7. 출시 관리자 각 스토어 트랙 확인 후 프로덕션 배포 & 심사 제출
십 년 묶은 뭔가가 내려간 것 같습니다. 혼돈의 카오스였던 앱 배포가 yarn version 커맨드 하나로 6번까지 자동화가 되었습니다. 이제 슬랙으로 알림을 받은 출시 관리자(아마도... 자동화를 한 본인일 가능성이 크겠죠...)가 출시 메시지와 함께 스토어에 게시만 하면 되는 것입니다.
자 이렇게 번 시간은 다른 일을 하는데 씁니다... 술을 먹으러 가도록 합시다.
이로써 웹 배포는 cloudbuild + git ops로 자동화되었고, 앱 배포는 circle CI + fastlane으로 자동화되었습니다. 개발자들은 개발에만 신경 쓰면 되는 것이죠! 정말 신이 나지 않습니까?