협업하다보면 꼭 필요한 부분이 바로 브랜치 전략(branch strategies)이다. 몇몇 팀을 경험하면서 느낀 점이 있다. 대부분의 팀이 gitflow를 채택해서 쓰고 있지만, 각 팀마다 전통적인 gitflow전략에서 조금씩(조금 많이...?) 변형을 주고 있었다. 그럼에도 불구하고 모두들 '우리는 gitflow를 쓰고 있어요'라고 이야기한다. 아마 처음 브랜치 전략을 세울 때 gitflow에서 시작했기 때문인 것 같다. 사실 개발하는 소프트웨어의 특성과 배포 방식이나 스케쥴에 따라서 알맞은 전략이 다르다. 그래서 전통적인 gitflow만을 고집하는 것도 융통성이 없는 것일지도 모르겠다.
최근에는 여러 버전의 피쳐를 동시에 개발하고, 각 버전별 테스트와 배포의 시간차가 거의 없는 팀의 브랜치를 들여다보게 되었다. 전통적인 gitflow로는 이러한 동시성을 커버 할 수 없는 걸까? 다른 브랜치 전략은 어떤 게 있을까? 더 적합한 전략이 있을까? 하는 고민을 해보다가 이 글을 작성한다.
GitFlow
가장 많이 알려진 전통적인 브랜치 전략이다. develop 과 master 브랜치를 기본으로 활용하고, 용도별로 feature, release, hotfix 브랜치를 사용한다.
ref:
master 브랜치는 배포된 안정적인 코드를 유지하는 용도로 이용되고, develop 브랜치에는 개발 중인 모든 코드가 모인다. feature 브랜치는 develop 브랜치를 base로 해서 생성되고 여기서 기능 개발을 진행한다. 개발이 완료된 feater 브랜치는 develop으로 다시 merge 한다. release 브랜치도 develop을 base로 브랜치가 생성되고, 배포를 위한 준비(테스트나 qa)를 하면서 발견된 버그를 수정해서 반영한다. 배포준비가 된 release 브랜치는 develop과 master에 머지하고, master에서는 tag를 단다. 그렇게 하면 release 브랜치에서 수정된 내용들이 develop에도 반영되고, master branch에서는 배포된 코드, 즉 안정적인 코드 버전을 보관할 수 있다. 만일 배포 후에 예상치 못한 문제 때문에 hotfix를 내보내야 하는 경우, master에서 hotfix 브랜치를 따서 수정한다. hotfix브랜치를 배포하고 나면 develop 과 master 브랜치에 각각 머지하고, master에 tag를 단다.
Github Flow
Github flow는 Git Flow가 너무 복잡하다는 의견과 함께 나왔다. main branch와 feature branch로만 운영되는 단순한 전략이다.
ref: https://docs.github.com/en/get-started/quickstart/github-flow
Github Flow에서 중요한 부분은 PR(Pull Request)이다. feature 에서 main으로 merge 되기 전에 PR을 통해 code review와 할수 있는 테스트를 모두 충분히 하고 수정한다. 그러면 main branch에는 모두 검증된 코드만 모이게 된다.
Gitlab Flow
git flow는 branch 종류가 너무 많고, github flow는 branch가 너무 단순하다며 나온 브랜치 전략이다. feature-driven development와 feature branch의 조합으로 만들어졌다.
ref: https://docs.gitlab.com/ee/topics/gitlab_flow.html
요즘 개발하는 방식이나 플랫폼이 전통적인 방식과는 맞지 않을 수도 있다. 특히 모바일 개발에서의 배포주기, Agile 방식의 채택 등은 좀 더 빠른 대응이 필요하기에 gitflow는 너무 헤비할 수 있다는 것이다. feature위주로 개발을 진행하고, 완성된 feature를 development(or main) branch에 머지한다.(여기까지는 github flow 와 같다.)
여기에 배포를 위한 production branch를 추가 한다. git flow의 master와 비슷한 역할을 한다. 하지만 master와는 조금 다르다. development(or main) branch의 특정시점에 배포하고 싶다면, 그때 production에 머지 요청을 하고, 이때 배포가 된다.(main branch에는 모두 검증된 코드만 모이기 때문에 언제든 배포해도 문제가 없다는 가정) 만일 배포 시점과 마켓 노출 시점이 다르다면(ios 처럼) 마켓에 노출된 뒤에 tag를 단다.
Gitlab flow 의 단순한 운영이 충분치 않은 경우, 다른 옵션도 있다. Environment 방식과 Release 방식이다. Release방식은 Opensource repository를 운영하는 경우 좋다고 한다. 여기서는 Environment 방식만 살펴볼거다.
Environment branches in GitLab Flow
테스트 환경에 따른 branch를 development(or main) 브랜치와 production 브랜치 사이에 두는 방식이다. 예를 들어 아래 그림처럼 staging, pre-prod 브랜치를 추가 할 수 있다. 만일 alpha / beta / real 이런 이름으로 서버를 운영한다면, 브랜치 이름을 alpha / beta / production(real) 로 운영해도 된다. 개발팀과 상황에 따라 정하면 되는 것 같다. 그리고 이 environment 브랜치들은 모두 일방향으로 머지되며, 머지 요청이 곧 배포이다. 즉, staging 환경에 배포하고 싶으면, staging브랜치로 머지 요청을 한다. 환경 브랜치들의 머지 요청은 모두 아래로 향한다.(This workflow, where commits only flow downstream, ensures that everything is tested in all environments.) 무슨말이냐하면.. develop -> staging -> pre-prod -> production 요 방향대로 머지가 진행되어야 한다는 것. 그래야 모든 환경에서 검증을 할 수 있기 때문에!
코드 검증 및 리뷰는 모두 development(or main)브랜치에 머지 될 때 발생한다. 따라서 내가 이해한 게 맞다면... staging환경에서 발생한 버그 수정은 다음과 같은 flow로 이루어진다.
1. 최신 develop에서 feature브랜치 생성 -> bug 수정 -> develop에 merge 요청 및 코드 리뷰 -> develop에 머지 -> staging에 머지 요청 (새 버전 배포)
2. 최신 develop에서 feature브랜치 생성 -> staging에서 발생한 모든 bug 수정해서 feature에 모은다 -> develop에 merge 요청 및 코드 리뷰 -> develop에 머지 -> staging에 머지 요청 (새 버전 배포)
1번과 같이 하면 버그 하나 수정할 때 마다 새로운 버전이 생긴다. 개인적으로는 2번 방법이 더 나아보인다. gitflow에서는 release branch에서 버그 수정과 배포를 모두 했다 gitlabflow는 모든 코드 수정은 feature에서 이루어지고, develop에 먼저 반영되어야 한다. (only flow downstream)
hotfix 역시 develop에서 feature를 따서 수정 후에 develop에 MR(PR과 같은 개념)을 요청한다. 그 뒤로 코드 검증이 완료되면 production으로 머지 요청을 해서 배포한다.
그동안 너무 gitflow만 맹신했던 건 아닌지, 예전 방식만 고수하는 꼰대가 되어버린 건 아닌지 한번 고민해볼 수 있는 좋은 기회였다. 확실히 앱의 배포는 기존 소프트웨어와는 조금 다른 부분이 있을 수도 있을 것 같다. gitflow를 쓰고 있지만, 대부분(아마도) github repository를 사용하면서 코드리뷰도 활발히 하고 있고, 머지 전에 자동화 테스트도 돌리고 있을 것이다. 결국은 github flow에서 말하는 것처럼 develop에 모이는 코드들은 이미 검증이 어느정도 된 상태이다. 조금 더 열린 마음으로 각 branch 전략을 살펴볼 필요가 있겠다.
사실 이 브랜치 전략들을 살펴본 계기는 "동시에 여러 버전의 기능이 개발되는 경우 어떤 게 더 효율적일까" 라는 고민이었다. 각 브랜치 전략이 어떻게 돌아가는 지 봤으니, 다음엔 위 질문에 대한 이야기를 해보려한다.
'개발 Story' 카테고리의 다른 글
iPad 기능. 어떤 걸 개발 해볼까. (0) | 2022.05.01 |
---|---|
Realm m1 issue. Could not find module 'RealmSwift' for target 'arm64-apple-ios-simulator'; found: i386, x86_64-apple-ios-simulator, x86_64, i386-apple-ios- simulator, at:`path` (0) | 2022.04.15 |
개발 속도를 올려주는 Xcode 단축키 모음 (0) | 2021.12.20 |
다중 작업이 동시에 끝날 때 까지 기다리려면 DispatchGroup (0) | 2021.12.07 |
REST API로 전환하면 "앱" 은 괜찮나요?(REST, RESTful API) (0) | 2021.10.07 |