Trunk-based development, Feature Flag, micro PR 와 함께 주 2회 배포하기

Wooseong Kim
29CM TEAM
Published in
11 min readSep 26, 2023
illustrated by DALL·E 3

안녕하세요, 29CM 모바일팀 리드/iOS 개발자 김우성입니다. 지난 글 이후 오랜만에 글을 작성하게 되었는데요, 이번 글에서는 저희 팀이 오랜 기간에 걸쳐 개선해 온 개발 프로세스에 대한 얘기를 해볼까 합니다.

저희 29CM 모바일팀은 전사적으로 추구하는 업무 문화인 29WAY 와 함께 지속적인 팀 성장과 프로세스 개선을 진행해오고 있있는데요, iOS팀에서는 이 목표를 달성하기 위해 지금까지 여러 도구를 도입하거나 프로세스를 시도해 왔었습니다.

그 중에서도 Trunk-based development, Feature Flag, micro PR 라는 세 가지 키워드와 함께 저희가 스쿼드/플랫폼에서 지속적으로 새로운 피쳐를 개발하면서도 주 2회 배포를 진행하는 업무 문화를 만들어 왔는지 소개드리려고 합니다.

1. Trunk-based development 와 Feature Flag

Trunk-based development 는 이름에서도 알 수 있듯 모든 개발자가 하나의 코드 브랜치인 ‘trunk’ 에서 작업을 진행하는 방식입니다. 이 방식은 여러 브랜치를 관리하는 복잡함을 줄여주며 지속적인 통합을 통해 코드의 품질과 안정성을 지속적으로 확보할 수 있게 해줍니다. 일반적으로 GitHub Flow 라고도 부릅니다.

저희 팀은 기존 두 개의 브랜치를 사용하던 Git Flow 에서, TBD 로 넘어오는 결정을 하게 되었는데 이를 위해 필요한 중요 인프라, Feature Flag 를 먼저 도입할 필요가 있었습니다.

Git Flow
GitHub Flow

Feature Flag 는 사용자에게 보이는 기능을 동적으로 토글할 수 있는 스위치로써, 서비스 중인 앱에 새로운 기능을 추가하거나 변경할 때 그 변경사항을 일부 사용자에게만 보이게 하거나 숨기는 데 사용됩니다. 이를 통해 저희 팀은 새로운 기능의 안정성을 테스트하면서도 실 사용자 환경에서의 피드백을 즉시 받을 수 있게 되었습니다.

저희 팀에선 각 Feature Flag 를 생성할 때 각 개발자가 다음과 같은 정보를 기입하도록 했고, 같은 파일 내에서 리스트를 관리하되 각 스쿼드/플랫폼 등 영역을 명시적으로 구분해서 어떤 스쿼드에서 어떤 피쳐들이 플래그로 분기가 되어 있는지 한 눈에 확인할 수 있도록 했습니다.
- 플래그 키
- 플래그 설명
- 피쳐 개발 상태 (개발중 / 카나리 배포 가능 / RC 배포 가능 / 릴리즈 가능 / 개발 중단)
- 담당자

//
// FeatureFlag+List.swift
//

/// A Squad
@objc public extension FeatureFlag {
static let searchResultAInventoryEnabled = FeatureFlag(
key: "searchResultAInventoryEnabled",
verbose: "검색 결과 화면에서 A 인벤토리를 볼 수 있습니다.",
stage: .readyForRelease(targetVersion: "5.79.0"),
owner: .personA
)
static let homeBannerYYExperimentEnabled = FeatureFlag(
key: "homeBannerExperimentYEnalbed",
verbose: "홈 배너 YY 실험을 진행합니다.",
stage: .readyForRelease(targetVersion: "5.97.0"),
owner: .personA
)

}

/// B Squad
@objc public extension FeatureFlag {
static let zzProgramEnabled = FeatureFlag(
key: "zzProgramEnabled",
verbose: "tt 상황에 zz 프로그램을 표시합니다.",
stage: .readyForRelease(targetVersion: "6.3.1"),
owner: .personC
)
}


/// Platform
@objc public extension FeatureFlag {
static let platformFeatureAEnabled = FeatureFlag(
key: "platformFeatureAEnabled",
verbose: "A 피쳐를 표시합니다.",
stage: .readyForRelease(targetVersion: "5.89.0"),
owner: .personD
)
}

2. Google’s changelist author’s guide

저희 팀의 사례를 소개하기에 앞서, Google의 사례를 먼저 소개하고자 합니다. Google은 하나의 모노레포에서 수만명이 개발하고 있는 것으로 유명한데요, Google이 지향하는 Changelist Author’s Guide 는 모노레포를 사용하는 많은 기업들에게 도움을 주는 가이드라인이 되어왔습니다.

Google이 지향하는 원칙, 왜 작은 CL을 작성해야 하는가? 를 가볍게 살펴보면 다음과 같습니다:

- 더 빨리 리뷰 받을 수 있고
- 더 철저하게 리뷰 받을 수 있고
- 버그를 생산할 가능성이 줄어들고
- 혹여 리젝되더라도 버려지는 양이 적고
- 머지하기 쉽고
- 설계를 잘 하기 쉽고
- 리뷰들 간의 블락이 줄어들고
- 롤백하기 쉬움

장점이 참 많죠? 이것 외에 또 중요하게 봐야 하는 점이 그 아래에 있는데요, ‘리뷰어는 CL이 너무 크다는 단 한 가지의 이유만으로 CL을 리젝할 권한이 있다’는 점입니다. 이미 크게 만들고 나면 분리하기가 쉽지 않을 수 있기에 처음부터 작은 CL을 작성하도록 권장하고 있습니다.

이러한 원칙은 저희 29CM 모바일팀이 추구하는 개발 방식과도 일치하는 부분이 많습니다. Google의 철학과 방법론을 참고하면서 오랜 기간에 걸쳐 저희 팀만의 원칙을 만들어 나가고 있는데요, 바로 저희가 micro PR 이라고 부르고 있는 협업 방식입니다.

3. micro PR

micro PR 은 ‘작은 변경’을 중심으로 한 풀 리퀘스트 방식입니다. 이 방법은 PR의 크기를 최소화하여, 리뷰 과정을 간소화하고 더욱 빠르게 개발을 진행할 수 있게 해줍니다. 단순한 코드 수정부터 복잡한 로직 변경까지, 모든 변경사항을 작은 단위로 관리하면서 전체 코드의 품질을 유지하는 것이 핵심입니다.

앞서 소개한 TBD와 Feature Flag 의 조합을 통해 micro PR을 작성할 수 있는 인프라가 갖추어졌는데요, 저희 팀에서의 각 피쳐들은 대략 아래와 같은 형태로 개발이 됩니다.

피쳐를 개발하는 첫 PR 에서, 일반적으로는 로컬 피쳐 플래그와 원격 피쳐 플래그인 Amplitude Flag 를 사용해 이중으로 분기 처리를 합니다. 아래에서 두 번째 PR을 보시면 `빈 추천 메인 화면을 추가합니다.` 라는 PR이 보이실 텐데요, 이런 식으로 실험군을 대상으로 분기 작업을 가장 먼저 해 두게 되면 그 이후의 작업 부터는 각 개발자가 PR를 작성할 때마다 사내 빌드가 정상적으로 아카이브 되도록 보장만 해 준다면 얼마든지 자유롭게 개발을 할 수 있는 환경이 조성되게 됩니다.

이렇게 micro PR 들이 레포에 모이게 되면 각 개발자들은 집중해서 자신의 개발을 진행하면서도 중간중간 짬이 날 때마다 최소한의 맥락을 가진 PR들을 리뷰하게 되면서 빠르게 리뷰할 수 있는 것들은 빠르게 리뷰 & 머지를 할 수 있게 됩니다. 이는 팀 차원에서 PR의 머지 리드 타임을 줄이고 더 빠른 배포를 할 수 있게 돕습니다. 이러한 PR들을 저희는 저맥락 PR이라 부르기도 합니다.

위 과정을 통해 설계적/구현적 관점에서 팀에서 좀 더 집중해서 리뷰해야 하는 PR 들만 따로 리뷰할 수 있는 환경이 되어, 구성원이 작업 과정에서 고민이 되었던 코드들은 더 좋은 구현을 위해 팀 차원에서 심도 있게 논의를 하곤 합니다. 기본적으로는 PR 내에서 비동기 커뮤니케이션으로 협업하지만 논의가 길어질 경우에는 페어 프로그래밍을 하기도 하고, iOS 팀 미팅에서 해당 건을 다같이 논의하기도 하면서 각 구성원이 더 좋은 결과물과 코드를 만들 수 있게 서포트를 하곤 합니다.

4. 앱을 주 2회 배포한다고?

위에서 소개드린 인프라와 팀의 문화가 작년 즈음 어느정도 정착을 되면서 기존 2~3주에 배포하던 프로세스를 주 1회 배포 프로세스로 바꾸게 되었습니다. 이를 위해 앱스토어 제출 프로세스도 대부분 자동화를 하게 되었는데, 이후 1년 정도 주 1회 배포를 계속 유지했지만 최근부터는 29CM 앱 고객에게 더욱 빠르게 가치를 전달하기 위해 모바일팀 내부 논의와 프로덕트 팀 협의를 거쳐 주 2회 배포 방식으로 바꾸게 되었습니다.

Tim Cook 사장님께서 매 릴리즈 시기마다 친절히 알려주십니다
Federighi 부사장님은 29CM iOS 앱의 배포 상태를 알려주십니다

이번 글의 제목을 ‘주 2회 배포하기’ 에 포커스하긴 했지만, 결과적으로는 앞서 소개드린 부분이 충분히 팀의 기반으로 자리잡았기 때문에 위와 같은 결정을 할 수 있었습니다. 이러한 프로세스는 TDD 기반으로 일을 하거나 테스트 커버리지를 중시하는 팀이 아닌 이상 일반적으로는 상당히 공격적인 배포 정책으로 인지는 하고 있습니다만, 저희 회사가 추구하는 문화 29WAY 중 ‘빠른 실행’‘고객 집중’을 위해 리스크를 일부 지면서도 더 자주 배포할 수 있는 팀으로 변화하게 되었다고 생각합니다.

물론 배포를 위한 리소스가 들지 않는 것은 아니기에, Canary/RC/Stable 등 여러 종류의 빌드를 지속적으로 배포하는 Continuous Delivery 를 구축해 두었고, 앱스토어 제출도 간단히 진행할 수 있는 자동화 프로세스를 GitHub Action 기반으로 구축해 두어 모바일 개발자의 부담을 최소화하기 위한 장치도 같이 마련하고 있습니다.

5. 앱 안정성도 챙겨야 하지 않나요?

저희 팀은 지속되는 피쳐 개발과 인프라 개선, 잦은 배포에도 위와 같이 오랜 기간 높은 Crash-free rate를 유지해오고 있습니다.

앱 안정성은 주 1회 배포를 할 때부터 지속적으로 팀이 고민해왔던 주제입니다. MAU가 점점 늘어나고 새롭게 개발하는 영역이 늘어나면서 스쿼드에서 배포 전에 미처 챙기지 못했던 엣지 케이스가 발생하거나 하는 경우는 종종 발생했고, 그로 인해 핫픽스를 진행하기도 했습니다.

하지만 저희가 릴리즈를 제출하기 직전의 RC 빌드에서 주요 피쳐를 검수하는 1-Pager Test를 그 주의 릴리즈 담당자가 간단히 진행한 뒤에 배포를 시작했기 때문에 아직까지는 다행히 Expedite Review 를 애플에 요청해야 하는 상황이 발생한 적은 없었습니다.

다만 주 2회 릴리즈를 하는 것은 저희 모바일 팀에도 부담이 되는 것은 사실이라, 최근에는 올해에 신설된 QA팀과 협업해 QA Engineering 을 통한 QA 자동화 파이프라인을 구축하고 있습니다. 이 프로세스가 완성되면 저희 모바일팀의 리소스 역시 이전보다 더 줄일 수 있을 것으로 기대하고 있습니다 :)

마치며

이번 글에서 소개드린 세 가지 핵심 인프라와 문화, Trunk-based development, Feature Flag(Local + Amplitude), micro PR 은 저희 29CM iOS 팀에게 큰 변화를 가져다 주었습니다.

이를 통해 더 빠르게 개발하고, 더 빠르게 리뷰하고, 더 빠르게 머지하며, 결과적으로 더 빠르게 고객에게 가치를 전달하면서도 동시에 일정 수준 이상의 앱 안정성도 같이 유지하는 것을 목표로 할 수 있게 되었습니다.

오늘 소개드린 내용이 팀 차원의 개발 문화와 인프라에 관심이 많으신 개발자 분들께 도움이 되셨길 바라면서 이번 글을 마치겠습니다!

.

함께 성장할 동료를 찾습니다

29CM (무신사) 는 3년 연속 거래액 2배의 성장을 이루었습니다.

더 나은 방향을 가기위해 노력하는, 위에서 소개드린 내용에 관심이 많고 좋은 조직문화를 함께 가꾸어나가길 원하는 동료 개발자분들을 찾습니다.

특히 저희 iOS 팀은 비즈니스/플랫폼 영역에서 홈 개편, 컨텐츠 개인화, 새로운 포맷의 컨텐츠 개발, QA 자동화 프로세스, 자동화 테스트 구축, 지속적인 모듈화를 통한 microFeature Architecture 구축, 감도 높은 사용성을 위한 웹뷰 고도화, 디버깅 인프라 개선 등 여러 도전 과제들과 함께 진행할 iOS 엔지니어를 모시고 있습니다.

저희 팀에 대해 궁금한 점이 있으시면 iosdev@29cm.com 으로 메일을 남겨주세요. 가벼운 티타임도 가능합니다!

저희 iOS 포지션을 비롯해 많은 지원 부탁드립니다 :)

🚀 29CM 채용 페이지 : https://www.29cmcareers.co.kr

--

--

Wooseong Kim
29CM TEAM

Software Craftman @ 29CM. Love books, coffee, simplicity. An enthusiastic follower of Steve Jobs.