66. GitLab Flow (깃랩 플로우) 브랜치 전략
⚠️ 이 문서는 한 달에 한 번 배포하는 낡은 'Git Flow'의 복잡함과, 코드 완성 즉시 무조건 운영 서버에 배포해 버리는 극단적인 'GitHub Flow'의 위험성 사이에서 타협점을 찾아, **소스 코드가 개발망(Dev) $\rightarrow$ 테스트망(Pre-Prod) $\rightarrow$ 운영망(Production)이라는 서버 환경(Environment)을 차례대로 통과하며 배포되도록 브랜치를 1:1로 매핑시킨 현실적이고 직관적인 전략인 'GitLab Flow'**를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 너무 복잡한
develop,release브랜치를 버리고main을 중심으로 두되, 코드가 배포될 서버 환경 이름(예:pre-production,production)을 딴 브랜치를 이어 붙여, 코드가 폭포수처럼 하류 환경으로 흘러 내려가게(Downstream) 만든 구조다.- 가치: 모바일 앱처럼 스토어 심사 기간이 필요하거나, 사내 결재가 떨어져야만 운영 서버에 배포할 수 있는 보수적인 엔터프라이즈 기업들이, CI/CD 자동화의 편리함을 챙기면서도 배포 타이밍을 마음대로 조절할 수 있는 유연성을 제공한다.
- 기술 체계: 모든 신규 기능은
feature브랜치에서 만들어져 무조건main브랜치로 병합(Merge)되며, 이후main$\rightarrow$pre-production$\rightarrow$production순서로만(역방향 금지) 코드를 머지하는 '환경 기반 릴리스(Environment-driven Release)' 규칙을 철저히 따른다.
Ⅰ. 양극단의 한계와 타협점의 모색
너무 무겁거나, 너무 가벼운 두 모델의 틈새를 파고들었다.
- Git Flow의 병합 지옥:
develop과release브랜치 사이에서 길을 잃고 얽히며, 배포 주기가 너무 길어 애자일(Agile) 속도전에 맞지 않는다.
- GitHub Flow의 무한 질주 공포:
main에 코드가 섞이면(Merge) 바로 상용 고객에게 배포(CD)된다. 자동화 테스트가 완벽하지 않은 일반 기업에서는 운영 서버가 터질까 봐 두려워 이 방식을 쓰지 못한다.
- GitLab Flow의 제안 (환경 매핑):
- "어차피 회사 서버는 개발 서버, 테스트 서버, 운영 서버 3개로 나뉘어 있지 않나? 그럼 브랜치도 딱 그 서버 개수만큼만 만들고 이름을 똑같이 지어버리자!"
- 코드가 특정 브랜치에 합쳐지는 행위 자체가 해당 서버로의 '배포 버튼' 역할을 하도록 CI/CD 파이프라인을 1:1 직관적으로 연결했다.
📢 섹션 요약 비유: Git Flow가 까다로운 서류 결재를 5번 거쳐야 물건을 출고하는 관료제 낡은 공장이라면, GitHub Flow는 물건을 만들자마자 바로 트럭에 실어 고객에게 던져버리는 극단적인 배달 업체입니다. GitLab Flow는 공장(Main) $\rightarrow$ 검수 창고(Pre-Prod) $\rightarrow$ 최종 매장(Prod)이라는 실제 건물의 순서대로 문을 열어주는 안전하면서도 상식적인 시스템입니다.
Ⅱ. GitLab Flow의 파이프라인 구조 (Upstream First)
물의 흐름을 거스르는 연어는 허용되지 않는다. 원칙은 상류에서 하류로만 흐르는 것이다.
- 규칙 1:
main브랜치는 영원한 상류(Upstream):- 개발자들이
feature가지를 파서 작업을 끝내면, 무조건 가장 먼저 합쳐지는 곳은main브랜치다. main브랜치에 코드가 섞이면, CI/CD 서버는 이 코드를 즉시 '개발(Dev) 서버'에 배포하여 개발자들이 기능이 잘 융합되었는지 확인하게 한다.
- 개발자들이
- 규칙 2: 환경 브랜치로의 폭포수 흐름 (Downstream):
main에서 문제가 없다고 판단되면, 다음 배포를 위해main의 코드를pre-production브랜치로 통째로 합친다(Merge). 이 순간 코드는 '테스트 서버'로 배포되어 QA팀의 승인을 받는다.- QA 승인이 떨어지면,
pre-production의 코드를production브랜치로 합친다. 이 순간 고객이 접속하는 진짜 '운영 서버'에 상용 배포가 일어난다.
- 규칙 3: Upstream First 원칙 (버그 픽스 경로):
- 만약 운영 서버(
production브랜치)에서 치명적 버그가 터지면 어떻게 할까? 운영 브랜치에서 직접 코드를 고쳐서 배포하는 것은 절대 금지다. - 반드시 상류인
main브랜치에서 버그를 먼저 고치고, 그 고친 코드를 다시 하류(pre-prod$\rightarrow$prod)로 차례대로 흘려보내야 한다. 이를 지키지 않으면 브랜치 간의 싱크가 박살이 난다 (체리픽 허용 예외 존재).
- 만약 운영 서버(
📢 섹션 요약 비유: 물은 항상 산꼭대기 옹달샘(main)에서 출발해 중간 저수지(pre-prod)를 거쳐 바다(prod)로 흘러가야 합니다. 바다 물이 더럽다고 바다에 직접 정수 약품을 타면(prod 직접 수정) 상류의 물은 여전히 더러운 채로 남습니다. 반드시 산꼭대기 옹달샘(main)에 약품을 풀어서 그 깨끗한 물이 다시 바다까지 흘러 내려오게 해야 강줄기 전체가 깨끗해진다는 절대 원칙입니다.
Ⅲ. 버전 기반 릴리스 (Release Branches)의 변형
모바일 앱처럼 '환경'이 아니라 '버전'으로 배포해야 하는 경우도 대처 가능하다.
- 소프트웨어 패키징 (App Store 등) 환경:
- SaaS 웹 서비스는 환경 브랜치가 맞지만, iOS 앱이나 오픈소스 라이브러리는 서버가 없으므로
1.1-stable,2.0-stable같은 버전 기반의 릴리스 브랜치를 사용한다.
- SaaS 웹 서비스는 환경 브랜치가 맞지만, iOS 앱이나 오픈소스 라이브러리는 서버가 없으므로
- 늦은 분기 (Late Branching):
- 처음부터
release브랜치를 파놓고 기다리는 Git Flow와 달리, GitLab Flow는main브랜치에서 2.0 버전을 위한 기능 개발을 쭈욱 다 끝내놓고, **"배포하기 직전"**에 마지막으로 늦게2.0-stable브랜치를 뚝 떼어낸다.
- 처음부터
- 버그 패치 (Cherry-pick):
- 2.0 버전이 앱스토어에 나갔는데 치명적인 로그인 버그가 터졌다.
- 이때도 'Upstream First' 원칙에 따라 무조건
main브랜치에서 버그를 먼저 고친 뒤, 수정한 특정 커밋(Commit) 딱 하나만 핀셋으로 집어내어(Cherry-pick)2.0-stable브랜치에 패치해 주는 세련된 방식을 취한다.
📢 섹션 요약 비유: 일단 공장 라인(main)에서 신제품 자동차 조립을 모두 끝마친 뒤, 출고장 문을 나서기 1분 전에야 트럭에 '2.0 에디션(release branch)'이라는 팻말을 붙여 밖으로 내보내는 방식입니다. 출고된 차에 리콜 사태가 터지면, 출고된 차에서만 결함을 고치는 게 아니라 반드시 공장 라인의 설계도(main)를 먼저 고치고 새 부품을 찍어서 출고된 차(2.0)에 갈아 끼워 주는(체리픽) 완벽주의를 추구합니다.