WooKoo Blog

물과 같이

개발/개발

포카마켓 iOS 팀의 여정(개발 전략 및 체계) - EP01

WooKoo 2024. 10. 14. 21:48

안녕하세요.

포카마켓 iOS 팀에서 개발을하고 있는 WooKoo 입니다.

 

지금까지 포카마켓의 iOS 팀을 빌딩하면서 어떤 방식과 나름의 고민으로 개발 전략을 구성하게 되었는지 이야기를 들려드리고자 합니다. 

 

2020년 03월 입사와 함께 아무 것도 존재하지않는 iOS 팀에 합류하게 되었습니다.

Xcode 프로젝트 조차 없었기에 회사에 프로젝트를 개설하는 첫 창조주가 되었습니다. 보통은 작은 레거시 프로젝트라도 있기 마련인데 말이죠..

 

1. 협업 충돌

모든 프로젝트와 마찬가지로 제 컴퓨터의 로컬에만 존재했던 프로젝트였습니다. 초기에는 정말 많은 프로젝트 설정들이 변경되어야했습니다. 단순 Main Storyboard 를 info.plist 부터 날리는 것부터 권한 설정 및 기타 설정 등 팀원과의 깃 충돌은 어마무시했습니다. 

 

가장 첫 시작은 gitignore 파일이었습니다. 빌드 시 생성되는 캐싱파일들조차 커밋 후에 올라가다보니 어느정도는 잠잠해졌지만 이것만으로는 해결되지 않았습니다. 

 

https://www.toptal.com/developers/gitignore

 

gitignore.io

Create useful .gitignore files for your project

www.toptal.com

 

해당 사이트에서 iOS, Xcode 에 필요한 이그노어 파일을 받고 팀에서 굳이 공유되어야하지 않아도 될 캐싱 파일들은 모두 리모트에서 제거하는 작업을 진행하였습니다.

그 뒤에는 커밋 시 스테이징에 캐싱파일이 잡히지않도록 되어 그나마 충돌을 줄일 수 있었으나 임시 조치에 불과했습니다.

 

결국 더 나은 방법을 찾아보다가 XcodeGen 이라는 무시무시한 친구를 알게 되었습니다. 

 

충돌을 안나게하는 방법은 많은 장점이 있는 XcodeGen 일부의 좋은 점이지만 이를 통해 XcodeGen과 모듈화 아키텍쳐에 대해서 알게되었고 이것이 현재 저희 프로젝트를 구성하는 Tuist 의 시작이었습니다.

(요즘은 너무나도 트렌드인 Tuist 이 당시만해도 아니었습니다.. 이는 추후에 다른 포스팅에서 자세히 다루겠습니다.)

 

또한 마이크로 PR 을 지향하고 있는데, 이 또한 충돌을 회피하고 코드 리뷰 시 리뷰어의 피로도를 낮춰주고, 조금 더 디테일하게 피드백을 받을 수 있는 좋은 기반이 되었던 것 같습니다.

 

 

2. 코드 리뷰

 

저희 팀은 깃허브의 PR 을 이용하여 코드 리뷰를 진행하고 있습니다. 어떤 이유로 코드리뷰를 하고 계신가요?

저희 팀은

 

1. 코드가 메인 브렌치에 병합 될 정도로 오류가 있지는 않나요?

2. 컨벤션은 지켜졌나요?

3. 더 나은 코드는 없나요?

4. 질문을 통해서 개발자 간 성장이나 인사이트를 줄 수 있나요?

 

등 의 목적을 가지고 진행합니다.

 

코드 리뷰를 직접 회의실에 모여서 진행하는 방식을 채택하는 팀들도 많겠지만, 많은 코드의 양을 한번에 보기에는 분량도 많고, 고민을 하고 제안을 할 수 있는 물리적인 시간 자체가 부족하게 됩니다.

 

코드리뷰에 관한 주의사항과 컨벤션 등의 내용은 지난 회고에서 작성한 내용을 참고해주시면 좋을 것 같습니다.

 

 

 

 

 

3. 브렌치 전략

 

초기에는 다들 사용하는 git flow 전략에 대해 도입을 고민하였습니다. 그러나 인원이 2명인 저희 팀에서 사용하기에는 마스터 브렌치까지의 절차가 너무나도 많아서 저희 팀과 맞지않다고 느꼈습니다. 규모가 크고 안정성이 갖춰진 프로젝트에서는 좋을 것 같은데, 신규 프로젝트에서 출시까지 앞 둔 프로젝트는 잦은 병합이 많기 때문에 더 그랬던 것 같습니다.

찾아보는 도중 github Flow 와 Trunk based 전략에 대해서 알게 되었는데, 저희는 github flow 전략을 택하였습니다.

이어지는 CI/CD 에서도 말씀드리겠지만 github flow 와 trunk based 는 마스터 브렌치에 바로 병합되기 때문에 오류가 날 수 있는 코드들을 바로바로 테스트 해볼 수 있는 환경이 거의 강제되어있습니다.

 

 

간단한 전략으로 러닝커브가 낮고 빠른 생산성의 효과를 가지고 있어서 저희 팀에 적합하다고 생각하여 해당 전략을 가지고 최근까지 개발을 해왔습니다.

 

그러나 깃헙 플로우 한계가 프로젝트를 진행하면서 다가왔습니다.

 

홈 화면 GNB 중 하나를 통째로 바꾸는 일을 개발하고 있었는데, 현재 배포 된 앱에서 특정 부분만 수정해서 다시 배포해 달라는 요청이 들어왔습니다.

 

이미 GNB 를 통째로 날린 상태에서는 깃헙 플로우의 마스터 브렌치에서는 다시 GNB 를 복구하여 작업 후 배포하기가 어려웠습니다. 

 

이를 해결 하는 방법은 두 가지가 있다고 생각했습니다.

 

하나는 기능 플래그를 이용하여 마스터 브렌치에 배포 되기 전 기능 GNB의 바뀐 내용을 분기처리 하는 방법입니다. 

둘 째는 배포 한 앱의 시점의 커밋에서 브렌치를 따고 수정 작업만 가져와 배포하는 방법입니다.

 

첫째 방법의 문제는 언젠가 큰 덩어리의 분기처리를 제거해줘야하고, 언젠가 분기처리를 제거하고, 하나라도 코드의 분기처리가 되지않으면 서비스에 큰 문제가 있을 수 있다는 가능성을 내포하고있습니다.

 

두번 째 방법의 문제는 마스터 브렌치와 수정한 브렌치 잘 병합되면 문제가 없지만 많이 달라진 마스터 브렌치의 경우에는 충돌이 나면 병합하는데의 문제를 가질 수 있어서 사용할 수 없었습니다.

 

그래서 고심 끝에 뱅크샐러드 iOS 팀에서 고민한 해결책을 알게되어 벤치마킹하게 되었습니다.

 

https://blog.banksalad.com/tech/how-banksalad-safely-deploys-mobile-app/

 

참고한 링크 추가합니다.

 

병합한 릴리즈와 마스터 브렌치의 차이를 두기위해 릴리즈에 반영되지않은 PR 의 경우에는 자동으로 Label 을 붙이도록 설정하였고, 병합 시 릴리즈에 병합된 PR 은 스크립트를 통해 Label 을 제거하는 방식을 채택하게되었습니다.

 

name: Add Pending Tag

on:
  pull_request:
    branches:
      - develop
    types:
      - closed

jobs:
  pending-label:
    runs-on: self-hosted
    if: github.event.pull_request.merged
    steps:
      - run: gh pr edit "$NUMBER" --add-label "🔗 Release Pending 🔗"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GH_REPO: ${{ github.repository }}
          NUMBER: ${{ github.event.pull_request.number }}

 

위 코드로 workflow 폴더에 스크립트를 적용시켜 주면 됩니다.

 

 

 

4. CI/CD

초기 XcodeGen 으로 프로젝트를 구성하고나서 CI/CD 를 구축해야겠다는 마음을 먹었습니다. 여러 파이프라인을 지원하는 도구 중에 당시 Apple 에서 제공하는 XcodeCloud 를 선택하게 되었는데 그 이유는 별도의 사이닝과 서버가 필요없이 빌드가 가능했고 생각보다 둘이서 사용하기에는 넉넉한 무료 시간이 있기에 선택하게 되었습니다. pre_script 라는 폴더 경로에 스크립트를 넣어줌으로써 클론 했을 당시와 빌드 전에 수행 할 수 있는 작업들을 명세해둘 수 있었고 Xcode 내에서도 진행상황 등을 확인 할 수 있는 편리한 기능이 제공되었습니다. 

 

그렇게 반기 정도를 사용한 뒤에 깃헙액션으로 돌아서게 되었습니다. 필요 시에만 앱을 아카이빙 하기에는 충분했으나 pr 마다 체크아웃하여 빌드를 돌려보는 작업이 어려워서 Firebase Distribution 과 로컬 맥북 하나를 서버로 두어 PR 마다 아카이빙을 하여 직접 앱에서 테스트 해보면서 배포 할 수 있도록 하기 위함이었습니다. 

 

 

 

그 외에도 지라와의 연동, 피그마를 통한 기획자와 디자이너와의 협업, 슬랙 연동, 노션, 컨플루언스 등 다양한 업무 도구와의 연결으로 지금까지의 팀 체계를 구축할 수 있었습니다.

 

다음 시간에는 iOS 개발 시 디버깅에 관한 내용들을 포스팅 해볼까합니다.

 

감사합니다.