- Published on
Trunk-based Development
현재 팀에서 여러개의 모노레포 프로젝트를 하나의 커다란 모노레포 프로젝트로 통합하는 작업을 진행하고 있다.
이 과정에서 어떤 브랜치 전략이 적합할지에 대해 고민하게 되었고, 대안 중 하나인 Trunk-based Development 에 대해 알아 본다.
거대한 모노레포를 운영하고 있는 구글, 페이스북에서도 trunk-based development 를 사용하고 있다. (참고 : https://dl.acm.org/doi/pdf/10.1145/2854146)
git flow 에서 가지고 있는 문제
1. Painful Merge
1) 기본적으로 브랜치 관리가 복잡하고, 이로 인해 merge 과정도 복잡하다.
예상되는 상황
- release 브랜치가 3개 열려 있는 상태에서 공통 lib 에서 이슈가 발견되어 hotfix 브랜치를 만들어 수정한다.
- hotfix 브랜치는 main, develop, release 3개 5번의 merge 가 필요하다.
2) long-lived branch 가 자주 발생하고, 이는 수많은 merge conflict 를 발생시키면서 리팩토링 등을 어렵게 만든다.

예상되는 상황
- release 브랜치를 만들고 여기에서 많은 수정들이 발생. 이후 배포가 3달 동안 지연되어 merge 되지 못하고 있음.
- 그 사이 develop 과 main 브랜치에는 여러 프로젝트들에 의해 리팩토링 등 많은 변경사항이 있었음.
- 위에서 만든 long lived release branch 를 develop, main 에 merge 하는 과정은 어렵고 예상치 못한 이슈를 발생시킬 수 있다. 이는 발견되지 못하고 배포될 수 있음.
수 많은 프로젝트가 생길수록 merge conflict 로 인해 리팩토링, 라이브러리 버전 업데이트 등은 점점 어려워질 수 있음.
2. 코드 리뷰 어려움 야기
브랜치가 오래 유지되어서 변경사항이 많으면, 주 브랜치에서 변경된 컨텍스트와 충돌이 발생하면서 코드리뷰에 어려움이 생길 수 있다.
Trunk-based Development
Trunk-based Development 가 무엇인가?

main(trunk) 라는 주 브랜치 하나만 운영하는 방식이다.
작업은 main 에서 이루어지거나, 몇일 내 (short-lived branch)로 main 으로 머지할 feature 브랜치에서 진행한다.
main 브랜치는 항상 배포 가능한 상태를 유지해야 한다.
feature, release, hotfix 도 존재하지만 다음과 같은 차이가 있다.
- feature : 가능한 짧게 유지하고, main 에서 생성하고, 머지한다.
- release : 모든 수정은 main 에서 진행하고, release 브랜치로 필요한 부분만 cherry-pick 한다.
- hotfix : release 와 동일하나, 안정성을 위해 마지막에 release 한 tag 에서 hotfix 브랜치를 생성하는 방식도 고려할 수 있다.
어떻게 운영해야 하나?

- PR 은 가능한 작은 작업 단위를 가져야 하며, 모든 commit 은 releasable 해야 한다.
- 장기간 지속되어야 하는 feature 는 feature flag 를 두어 기능을 on/off 한다.
- 자동화된 효과적인 테스트 전략 필요
release flow
- release 브랜치 생성 시, 모든 수정은 main 에서 진행하고, release 브랜치로 필요한 부분을 cherry-pick 한다.
- main에 없는 commit이 release 에 존재해서는 안됨
- release 브랜치는 main 으로 merge 하지 않는다.
- release 완료 후 release branch 에서 version tagging

hotfix flow
- hotfix 도 release flow 와 동일하게 main 에서 진행하고, hotfix 브랜치로 cherry-pick 한다.
- 안정성을 위해 이전에 release 한 tag 에서 hotfix 브랜치를 생성하는 방식도 고려할 수 있다.
feature flag
feature flag 를 통해 기능을 on/off 하는 방식으로, 작업이 완료되지 않거나 사용자에게 노출되지 않아야 하는 feature 를 disable 할 수 있다.
- feature flag 는 가능한 적게 사용하고, 완료되면 제거된다.
- hotfix 를 release 한 tag 에서 진행한다면, feature flag 는 거의 사용하지 않고, 한 프로젝트에서 장기 개발 진행하는 feature 가 있는 동시에 release 를 진행하는 경우에만 사용하게 되지 않을까..

git flow 와 장단점 비교
장점

단점
- main 에서 수정하고, cherry-pick 하는 방식은 번거로움이 있을 수 있다.
- feature flag 를 두기 위한 공수가 필요하다.
- 버그가 main 에 바로 반영될 수 있다. -> hotfix 를 release 한 tag 에서 진행한다면 괜찮지 않을까?