안전제일! 뱅크샐러드가 모바일 앱을 안정적으로 배포하는 방법

안전제일! 뱅크샐러드가 모바일 앱을 안정적으로 배포하는 방법

지난 글에서는 뱅크샐러드 iOS 프로젝트의 구조 문제를 소개하고 이를 어떻게 개선했는지 사례를 소개 드렸습니다. 대규모 리팩토링은 프로젝트 전체에 영향을 미치기 때문에 의도치 않은 버그가 발생하기 쉽습니다. 그러나 다행히도 일련의 개선 과정을 큰 문제 없이 사용자에게 배포할 수 있었습니다.

iOS 챕터가 큰 변화를 두려움 없이 시도할 수 있는 배경에는 iOS 챕터 구성원끼리 그리고 QA, CX 팀과의 긴밀한 협업이 뒷받침되었기 때문입니다. 이번 글에서는 각 조직이 매주 안정적으로 모바일 앱을 배포하기 위해 어떻게 협업하고 있는지 소개 드리려 합니다. 이 글은 iOS 챕터의 사례를 소개 드리지만 안드로이드 챕터의 프로세스도 유사한 형태를 띠고 있습니다.


낙장불입

모바일 앱은 새 버전을 배포하면 해당 버전 배포를 되돌릴 수 없습니다.

문제가 발생하면 수정 버전을 배포해 문제를 해결해야 합니다. 수정 버전을 배포하기 위해서는 스토어 심사를 거쳐야 하는데 이 과정은 짧으면 몇 시간, 길게는 며칠이 소요될 수 있습니다. 수정 버전을 배포하더라도 기존 버전을 다운로드한 사용자가 강제로 수정 버전을 사용하게 하는 것은 어렵습니다.

이 때문에 모바일 앱을 배포할 때는 항상 안전제일이란 마음가짐으로 접근해야 합니다. 그럼에도 불구하고 발생할 수 있는 예상치 못한 문제를 최소화하기 위해 다양한 장치가 준비되어 있습니다.


배포 루틴

매주 반복되는 릴리즈 프로세스를 도식화한 이미지

모바일 앱의 배포는 서버나 웹과는 다른 과정을 거칩니다. 각 플랫폼의 스토어를 통해 배포해야 하고 업데이트를 할 때마다 스토어 심사를 거쳐야 합니다. 스토어에서 새 버전을 배포해도 사용자의 기기에 새 버전이 설치되지 않으면 사용자는 구 버전을 계속 사용하게 됩니다.

이러한 특성으로 인해 변경사항이 생길 때마다 배포하는 것은 무리가 있습니다. 이 문제의 타협점을 찾고 서비스를 안정적으로 운영하기 위해 위해 저희는 정기 배포 루틴을 만들었습니다.

배포는 매주 진행합니다. 버전은 배포가 이뤄지는 주차에 따라서 명명됩니다. 예를 들어 2023년 48주 차에 배포되는 버전은 23.48.* 버전이 됩니다.

  • 개발 첫 1주일은 기능을 개발하는 시간입니다. 기능을 기획할때 부터 1주일 사이클을 고려해 기능을 독립 가능한 단위로 작게 나누어 자주 사용자에게 배포하는 전략을 세웁니다.
  • 자동화 테스트 금요일 오후에 release 브랜치가 분리되고 테스트를 위한 빌드를 사내 배포합니다. 이때부터 주말 동안 QA 팀은 자동화 테스트를 진행합니다.
  • Release QA 다음 한 주 동안 Release QA를 진행합니다. QA 팀에서 주요 기능 및 신규 기능을 테스트하고 발견한 이슈를 iOS, Android 챕터에 전달합니다. iOS, Android 챕터는 이슈를 해결한 후 다시 테스트 빌드를 QA 팀에 전달합니다. 이 사이클을 1-2회 정도 반복합니다.
  • 스토어 심사 중요도 높은 이슈가 모두 해결되면 QA 팀에서 이제 배포해도 좋다는 의견을 iOS, Android 챕터에 전달합니다. 이때 iOS, Android 챕터는 스토어에 심사를 제출합니다. 심사는 대부분 주말 중에 완료됩니다.
  • 점진적 배포 월요일부터 수요일까지 점진적 배포를 진행합니다. 이 기간 동안 새 버전에 문제가 없는지 관찰합니다.
  • 전체 배포 점진적 배포 기간 동안 이상이 없다면 전체 배포를 진행합니다.

각 과정의 상세한 내용은 아래와 같습니다.


준비

프로덕트 스펙과 테크 스펙

'뱅크샐러드의 특별한 스펙, 테크스펙' 이라고 크게 적혀있는 이미지

개발에 들어가기 전에 프로덕트 스펙과 테크 스펙으로 앞으로의 계획을 설계하고 공유합니다. 제품의 크기, 실험 진행 여부에 따라 프로덕트 스펙 혹은 테크 스펙을 생략하거나 추가 문서를 작성하기도 합니다.

  • 프로덕트 스펙은 개발하는 기능의 목적과 명세를 포함합니다. 단순한 기능이라면 프로덕트 스펙을 생략하고 Figma 만으로 진행하기도 합니다. 실험이 포함된 기능이라면 실험 설계 문서를 동반합니다. 실험에 관한 내용은 진정한 실험 조직의 탄생 글을 참고해 주세요.
  • 테크 스펙은 앞으로의 개발, 배포, 모니터링 계획을 포함합니다. 기능이 복잡하거나 구현 방법이 다양할 경우에는 테크 스펙으로 작업 계획을 제시한 후 리뷰를 요청합니다. 이를 통해 다른 구성원과 함께 더 나은 해결책을 고민할 수 있고 코드 리뷰 단계에서 의견 충돌을 최소화할 수 있습니다. 자세한 내용은 뱅크샐러드의 특별한 스펙, ‘테크 스펙’ 글을 참고해 주세요.

개발

개발 단계의 브랜치 전략

개발 기간에 브랜치를 관리하는 전략을 도식화한 이미지

develop 브랜치를 기본 브랜치로 삼습니다. 기능을 개발할 때는 develop 브랜치로부터 feature 브랜치를 생성합니다. feature 브랜치를 develop 브랜치에 병합할 때는 squash and merge 방식을 사용합니다. develop 브랜치에 병합하기 위해서는 모든 테스트를 통과해야 하고 당장 사용자에게 배포해도 문제가 없는 상태여야 합니다.

각 feature 브랜치는 가능한 작은 변화만을 포함하고 짧은 기간 내에 develop 브랜치에 병합해야 합니다. 이를 위해 작은 PR 규칙과 실험 플랫폼을 적극 활용합니다. 이 덕분에 대규모 리팩토링을 할 때도 다른 작업과 충돌을 최소화할 수 있었습니다. 자세한 내용은 코드리뷰 in 뱅크샐러드 개발 문화 > ‘작은 PR’과 ‘실험 플랫폼’을 이용한 유연한 모바일 서비스 출시 문단에서 소개하고 있습니다.

release 브랜치와 배포용 빌드는 매주 금요일에 생성합니다.


코드리뷰

'코드리뷰 in 뱅크샐러드 문화' 라고 크게 적혀있는 이미지

작업이 완료되면 코드 리뷰 과정을 거칩니다. 뱅크샐러드는 빠르고 퀄리티 좋은 코드 리뷰를 위해 몇 가지 규칙을 만들었습니다.

코드 오너는 PR 본문과 테크 스펙으로 작업에 대한 문맥을 미리 제공하고 작은 PR 규칙으로 변경 사항에 집중할 수 있도록 리뷰어를 돕습니다. 리뷰어는 주어진 맥락과 변경사항을 이해하고 Pn 룰 등을 이용해 자신의 의견을 전달합니다. 리뷰어 1명 이상의 승인이 나면 develop 브랜치에 병합할 수 있습니다. 최소 인원이 1명일 뿐이고 필요에 따라 더 많은 인원의 리뷰를 받을 수도 있습니다.

개인적으로는 뱅크샐러드 개발 문화의 꽃이라고 생각하는데요, 자세한 내용은 코드 리뷰 in 뱅크샐러드 개발 문화 글에서 소개하고 있습니다.


테스트

Mac mini 3대가 세로로 쌓여있고 자동 테스트를 실행하는 이미지

develop 브랜치에 병합되기 전에 테스트를 통과해야 합니다. 테스트는 Github Actions로 트리거 하고 자체 Mac 시스템 이용해 진행합니다. 테스트 코드를 모두 통과하는지, 빌드 세팅에 변경이 없는지 등을 체크합니다. 테스트에 대해서는 뱅크샐러드 iOS팀이 숨쉬듯이 테스트코드 짜는 방식에서 자세하게 다룹니다.


Release QA 리스크 분석

QA팀이 Release QA 리스크 분석 리뷰를 요청하는 메시지

매주 금요일이 되면 QA 팀에서 지난 한 주 동안 생성된 Jira 티켓을 바탕으로 Release QA 단계에서 유의해야 할 점을 분석해 문서로 전달합니다. iOS, Android 챕터 구성원은 이 문서를 보고 추가로 주의가 필요한 부분이 있다면 전달합니다.

문제가 생길 수 있는 화면 목록을 나열한 표

특히 앱 전역에 영향을 미치는 대규모 리팩토링을 할 때는 의도치 않은 버그가 발생할 수 있기 때문에 적극적으로 도움을 요청합니다.

이때 해당 리팩토링이 어떤 변경을 포함하며 어떤 화면이 주의 대상인지 등을 테크 스펙에 미리 기입해둔다면 도움이 됩니다. 미리 영향 범위를 정리해두었기 때문에 작업 과정에서 실수를 줄일 수 있고, 코드 리뷰 과정에서 다른 구성원의 리뷰를 도울 수 있고, Release QA 과정에서 구체적으로 테스트를 요청드릴 수 있어 일석삼조 효과가 있습니다.


release 브랜치, 테스트 빌드 생성

테스트 빌드가 완성되었다고 공지하는 메시지

매주 금요일 오후에 해당 주차의 작업이 마무리되면 develop 브랜치로부터 release 브랜치를 생성하고 release 브랜치를 기준으로 사내 테스트를 위한 빌드를 생성합니다. iOS 챕터 각 구성원은 2주마다 번갈아가며 이 일을 담당하는 builder 역할을 수행합니다.

빌드에 성공했을 때와 실패했을 때 전달되는 메시지

배포 또한 GitHub Actions + 자체 Mac 시스템에서 이뤄집니다.

  1. 각 개발자의 로컬 환경에서 간단한 배포 명령어를 입력합니다.
  2. 자체 Mac 시스템에서 Dev, Alpha, Beta, Production 빌드를 생성하는 Workflow가 실행됩니다.
  3. Workflow 진행 상황에 따라 적절히 Slack을 통해 알림이 전달됩니다.
    • 빌드에 성공한다면 Testflight 등을 통해 사내 구성원에게 배포됩니다.
    • 빌드에 실패한다면 실패 사유가 Slack 메시지를 통해 전달됩니다.

Release QA

자동화 테스트

release 브랜치가 생성되면 QA 팀은 주말 동안 자동화 테스트를 진행합니다. 자동화 테스트는 GitHub Actions에서 트리거 하고 자체 Mac 시스템에서 동작합니다. 자체 Mac 시스템에는 iOS, Android 실제 디바이스가 연결되어 있습니다.

QA 팀은 자동화 테스트 덕분에 적은 인원에도 불구하고 넓은 범위를 짧은 시간 동안 효율적으로 테스트하고 있습니다.


이슈 전달

릴리즈 테스트에서 발견된 이슈를 모아둔 보드

QA 팀에서 자동화 테스트를 포함해 앱 전체에 걸친 테스트를 끝내면 iOS, Android 챕터에 Jira 티켓으로 발견된 이슈를 전달합니다. 각 티켓에는 수행 환경, 재현 방법, 우선순위가 포함되어 있습니다. iOS, Android 챕터는 이틀 정도 시간을 가지고 발견된 이슈를 해결하고 해당 내용을 포함해 테스트 빌드를 다시 전달합니다.

위 사이클을 1-2번 정도 반복합니다. 그리고 목-금요일쯤 우선순위가 높은 이슈가 모두 해결되면 QA 팀에서 배포해도 좋다는 의견을 iOS, Android 챕터에 전달합니다. 만약 시간 내에 이슈가 해결되지 않는다면 해당 기능만 배포 버전을 미루어 문제를 해결하고 배포합니다.


Release 단계의 브랜치 전략

Release QA 기간에 브랜치를 관리하는 전략을 도식화한 이미지

이슈 해결 브랜치도 feature 브랜치와 동일하게 취급합니다. develop 브랜치에서 생성되며 작업이 끝나면 develop 브랜치에 squash and merge 합니다. 이때 병합된 브랜치의 commit hash 값을 모아뒀다가 patch 버전이 1 오른 release 브랜치를 생성할 때 cherry-pick 하고 해당 release 브랜치를 기준으로 사내 테스트 빌드를 생성합니다.

예를 들어 23.48.0 버전에서 발견된 이슈를 해결하는 작업 브랜치는 develop 브랜치에서 생성하고 develop 브랜치에 병합합니다. 이후 23.48.0 버전 이슈 해결 기간이 끝날 때 release/23.48.0 브랜치에서 release/23.48.1 브랜치를 생성하고 develop 브랜치에 병합한 이슈 해결 commit을 release/23.48.1 브랜치에 cherry-pick 합니다. 그리고 release/23.48.1 브랜치를 기준으로 23.48.1 버전 빌드를 생성합니다.

얼핏 보기엔 Git Flow와 유사해보이지만 다른 점이 존재합니다.

1. release 브랜치 운영 방법

이슈 해결 브랜치를 develop에서 생성하고 병합하는 것은 ‘각 feature 브랜치는 가능한 작은 변화만을 포함하고 짧은 기간 내에 develop 브랜치에 병합해 최신 상태를 유지한다’라는 기본 규칙을 지키기 위함입니다.

만약 release 브랜치에서 이슈 해결 브랜치가 생성/병합된다면 해당 변경 사항은 release 브랜치를 finish 하기 전까지 develop 브랜치에 반영하지 못합니다. 이 때문에 develop 브랜치에서는 이슈가 해결되지 않은 것처럼 보이는 문제가 생깁니다. 또한 release 브랜치를 finish 할 때 많은 변경점이 생겨 충돌을 해결하기 어려운 문제도 생깁니다.

그러나 모든 브랜치를 develop 브랜치에서 생성/병합 한다면 앞서 언급한 문제점들을 해결할 수 있습니다. 또한 구성원은 각자의 feature 브랜치가 develop 브랜치와 충돌하는 지만 관리하면 되기 때문에 신경써야 할 지점이 줄어듭니다. 이마저도 앞서 언급한 작은 PR과 실험 플랫폼의 조합으로 충돌에 대한 스트레스를 0에 가깝게 만들 수 있습니다.

대신 release 브랜치로 이슈 해결 commit을 cherry-pick 할 때 충돌이 발생할 수 있습니다. 이는 작업 시점으로부터 한참 뒤에 develop, feature 브랜치에서 충돌이 나는 것보다 얼마 지나지 않아 release 브랜치에서 충돌이 발생하도록 만드는 편이 충돌 해결에 코스트가 덜 든다고 판단하에 감내하기로 한 trade-off입니다.

2. main(master) 브랜치의 역할

Git Flow에서 main(master) 브랜치는 크게 2가지 역할을 가지고 있습니다.

첫째는 언제나 배포 가능한 상태의 코드를 반영하는 역할입니다. 그러나 저희는 이 역할을 develop 브랜치에 부여했습니다. develop 브랜치에 병합하기 위해서는 모든 테스트를 통과해야 하고 개발이 끝나지 않은 기능은 Feature Flag를 이용해 사용자가 접근하지 못하도록 방어합니다. 이 덕분에 develop 브랜치는 언제든지 사용자에게 배포 가능한 상태를 유지합니다.

둘째는 배포된 상태의 형상을 Tag 등으로 관리하는 역할입니다. 그러나 저희는 이 역할을 release 브랜치에 부여했습니다. 모든 기능 수정은 develop 브랜치를 기반으로 작업하고 release 브랜치는 변경사항을 모아서 한 번에 cherry-pick만 합니다. 이 때문에 release 브랜치는 최초 생성 시점 이후에 변경이 발생하지 않아 안정된 상태를 유지합니다. 이 점을 활용해 release 브랜치를 아카이빙 목적으로 사용하고 있습니다.

이로 인해 main(master) 브랜치의 역할은 다소 퇴색되어 현재 사용자에게 배포된 최신 버전의 형상을 투영하는 정도로만 사용하고 있습니다.


스토어 심사

Release QA를 끝내면 마지막 빌드로 스토어에 심사를 제출합니다. 대부분은 주말 사이 심사가 끝나기 때문에 월요일이 되면 배포할 준비가 되어 있습니다.

심사 제출 상태 확인을 요청하는 봇

심사 제출 과정에서 builder의 실수를 줄이기 위해 Slack 봇을 활용합니다.


점진적 배포

점진적 배포를 시작했다고 알리는 메시지

월요일 오후부터 이틀간 점진적 배포 기간을 가집니다. 앱스토어의 자동 업데이트의 점진적 출시 기능을 이용하면 업데이트 버전을 배포해도 전체 사용자 중 일부만 자동으로 업데이트됩니다. 이 기간에 자동 업데이트되는 사용자는 전체의 5% 정도입니다. 이 기간 동안 모니터링 툴을 이용해 새 버전에 문제가 없는지 관찰합니다.


전체 배포

점진적 배포 기간 동안 배포 버전에 문제가 없음을 확인하고 전체 배포를 진행한다고 알리는 메시지

이틀간 점진적 배포 기간을 가진 후 지표에 문제가 없고 해당 버전에서 들어온 특이 고객 문의가 없다고 판단되면 전체 배포를 진행합니다.

점진적 배포 기간 동안 배포 버전에 문제를 확인하고 핫픽스를 진행한다고 알리는 메시지

점진적 배포 기간동안 지표에 이상이 발견되거나 특이 고객 문의가 들어오면 점진적 배포를 중단하고 hotfix 빌드를 배포해 대응합니다.

전체 배포 이후 대시보드를 체크하고 이상이 없는지 확인하는 메시지

전체 배포 이후에도 크래시 여부 등 지표를 꾸준히 관찰합니다. 뒤늦게 발견되는 이슈가 있다면 중요도에 따라 hotfix 빌드를 배포해 대응하거나 다음 배포 버전에 수정 내용을 포함시킵니다.


긴밀한 협업이 가져다준 이점

여기까지 각 조직이 매주 안정적으로 모바일 앱을 배포하기 위해 어떻게 협업하고 있는지 소개 드렸습니다. 일련의 과정에서 어떤 이득을 볼 수 있을까요?

  1. 일관된 퀄리티를 유지할 수 있습니다. 개개인의 역량보다 전체 조직의 운영 프로세스와 자동화된 시스템에 의존하기 때문입니다.
  2. 사용자에게 발생하는 문제를 최소화할 수 있습니다. 업데이트는 철저한 테스트를 거쳐 배포되므로 예기치 못한 문제 발생 가능성이 현저히 낮아집니다.
  3. 챕터 구성원의 심적 부담을 줄여줄 수 있습니다. 각 단계에서 안전망이 마련되어 있기 때문에 구성원은 안정적인 환경에서 작업할 수 있습니다. 또한 배포가 특별한 일이 아니라 일상적인 루틴이 되기 때문에 배포라는 행위 자체를 가볍게 받아들일 수 있습니다.

이와 같은 다양한 장점들이 결합되어 사용자 경험을 향상시키고 팀의 생산성과 안정성을 동시에 높일 수 있었습니다.


마치며

하반기 동안 많은 리팩토링 작업을 진행했는데 모든 과정에서 조직의 뒷받침이 있었기에 자신감을 가지고 속도를 낼 수 있었다는 생각이 들어 이 과정을 여러분께 소개 드렸습니다.

뱅크샐러드는 각 조직이 각자의 일을 탄탄하게 하는 것은 물론 조직 사이 효율적인 협업을 위해서도 많은 노력을 들이고 있습니다. 그러나 여전히 할 일이 많기 때문에 앞으로 함께할 새로운 엔지니어 분을 찾고 있습니다. 저희와 함께 일당백을 위해 노력할 준비가 되신 엔지니어 분이 계신다면 아래 지원하기 버튼을 눌러 지원 부탁드립니다!

읽어주셔서 감사합니다 :)

보다 빠르게 뱅크샐러드에 도달하는 방법 🚀

지원하기

Featured Posts

post preview
post preview
post preview
post preview
post preview

Related Posts