66. GitLab Flow (깃랩 플로우) 브랜치 전략

⚠️ 이 문서는 한 달에 한 번 배포하는 낡은 'Git Flow'의 복잡함과, 코드 완성 즉시 무조건 운영 서버에 배포해 버리는 극단적인 'GitHub Flow'의 위험성 사이에서 타협점을 찾아, **소스 코드가 개발망(Dev) $\rightarrow$ 테스트망(Pre-Prod) $\rightarrow$ 운영망(Production)이라는 서버 환경(Environment)을 차례대로 통과하며 배포되도록 브랜치를 1:1로 매핑시킨 현실적이고 직관적인 전략인 'GitLab Flow'**를 다룹니다.

핵심 인사이트 (3줄 요약)

  1. 본질: 너무 복잡한 develop, release 브랜치를 버리고 main을 중심으로 두되, 코드가 배포될 서버 환경 이름(예: pre-production, production)을 딴 브랜치를 이어 붙여, 코드가 폭포수처럼 하류 환경으로 흘러 내려가게(Downstream) 만든 구조다.
  2. 가치: 모바일 앱처럼 스토어 심사 기간이 필요하거나, 사내 결재가 떨어져야만 운영 서버에 배포할 수 있는 보수적인 엔터프라이즈 기업들이, CI/CD 자동화의 편리함을 챙기면서도 배포 타이밍을 마음대로 조절할 수 있는 유연성을 제공한다.
  3. 기술 체계: 모든 신규 기능은 feature 브랜치에서 만들어져 무조건 main 브랜치로 병합(Merge)되며, 이후 main $\rightarrow$ pre-production $\rightarrow$ production 순서로만(역방향 금지) 코드를 머지하는 '환경 기반 릴리스(Environment-driven Release)' 규칙을 철저히 따른다.

Ⅰ. 양극단의 한계와 타협점의 모색

너무 무겁거나, 너무 가벼운 두 모델의 틈새를 파고들었다.

  1. Git Flow의 병합 지옥:
    • developrelease 브랜치 사이에서 길을 잃고 얽히며, 배포 주기가 너무 길어 애자일(Agile) 속도전에 맞지 않는다.
  2. GitHub Flow의 무한 질주 공포:
    • main에 코드가 섞이면(Merge) 바로 상용 고객에게 배포(CD)된다. 자동화 테스트가 완벽하지 않은 일반 기업에서는 운영 서버가 터질까 봐 두려워 이 방식을 쓰지 못한다.
  3. 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. 규칙 1: main 브랜치는 영원한 상류(Upstream):
    • 개발자들이 feature 가지를 파서 작업을 끝내면, 무조건 가장 먼저 합쳐지는 곳은 main 브랜치다.
    • main 브랜치에 코드가 섞이면, CI/CD 서버는 이 코드를 즉시 '개발(Dev) 서버'에 배포하여 개발자들이 기능이 잘 융합되었는지 확인하게 한다.
  2. 규칙 2: 환경 브랜치로의 폭포수 흐름 (Downstream):
    • main에서 문제가 없다고 판단되면, 다음 배포를 위해 main의 코드를 pre-production 브랜치로 통째로 합친다(Merge). 이 순간 코드는 '테스트 서버'로 배포되어 QA팀의 승인을 받는다.
    • QA 승인이 떨어지면, pre-production의 코드를 production 브랜치로 합친다. 이 순간 고객이 접속하는 진짜 '운영 서버'에 상용 배포가 일어난다.
  3. 규칙 3: Upstream First 원칙 (버그 픽스 경로):
    • 만약 운영 서버(production 브랜치)에서 치명적 버그가 터지면 어떻게 할까? 운영 브랜치에서 직접 코드를 고쳐서 배포하는 것은 절대 금지다.
    • 반드시 상류인 main 브랜치에서 버그를 먼저 고치고, 그 고친 코드를 다시 하류(pre-prod $\rightarrow$ prod)로 차례대로 흘려보내야 한다. 이를 지키지 않으면 브랜치 간의 싱크가 박살이 난다 (체리픽 허용 예외 존재).

📢 섹션 요약 비유: 물은 항상 산꼭대기 옹달샘(main)에서 출발해 중간 저수지(pre-prod)를 거쳐 바다(prod)로 흘러가야 합니다. 바다 물이 더럽다고 바다에 직접 정수 약품을 타면(prod 직접 수정) 상류의 물은 여전히 더러운 채로 남습니다. 반드시 산꼭대기 옹달샘(main)에 약품을 풀어서 그 깨끗한 물이 다시 바다까지 흘러 내려오게 해야 강줄기 전체가 깨끗해진다는 절대 원칙입니다.


Ⅲ. 버전 기반 릴리스 (Release Branches)의 변형

모바일 앱처럼 '환경'이 아니라 '버전'으로 배포해야 하는 경우도 대처 가능하다.

  1. 소프트웨어 패키징 (App Store 등) 환경:
    • SaaS 웹 서비스는 환경 브랜치가 맞지만, iOS 앱이나 오픈소스 라이브러리는 서버가 없으므로 1.1-stable, 2.0-stable 같은 버전 기반의 릴리스 브랜치를 사용한다.
  2. 늦은 분기 (Late Branching):
    • 처음부터 release 브랜치를 파놓고 기다리는 Git Flow와 달리, GitLab Flow는 main 브랜치에서 2.0 버전을 위한 기능 개발을 쭈욱 다 끝내놓고, **"배포하기 직전"**에 마지막으로 늦게 2.0-stable 브랜치를 뚝 떼어낸다.
  3. 버그 패치 (Cherry-pick):
    • 2.0 버전이 앱스토어에 나갔는데 치명적인 로그인 버그가 터졌다.
    • 이때도 'Upstream First' 원칙에 따라 무조건 main 브랜치에서 버그를 먼저 고친 뒤, 수정한 특정 커밋(Commit) 딱 하나만 핀셋으로 집어내어(Cherry-pick) 2.0-stable 브랜치에 패치해 주는 세련된 방식을 취한다.

📢 섹션 요약 비유: 일단 공장 라인(main)에서 신제품 자동차 조립을 모두 끝마친 뒤, 출고장 문을 나서기 1분 전에야 트럭에 '2.0 에디션(release branch)'이라는 팻말을 붙여 밖으로 내보내는 방식입니다. 출고된 차에 리콜 사태가 터지면, 출고된 차에서만 결함을 고치는 게 아니라 반드시 공장 라인의 설계도(main)를 먼저 고치고 새 부품을 찍어서 출고된 차(2.0)에 갈아 끼워 주는(체리픽) 완벽주의를 추구합니다.