핏펫몰 개발 스쿼드의 git 전략 연대기
핏펫몰 개발을 진행하면서 좌충우돌 계속 바꿔왔던 git 전략을 정리해보았습니다. 그 때 그 때 최선이라고 여겼던 git 전략은 개발 페이즈에 따라, 스쿼드사이즈에 따라 계속 바뀌어야 했습니다.
암흑의 시대
핏펫몰 개발이 처음 시작되었을 때는 개발자도 소수였고, 런칭까지 일정이 촉박했기 때문에 자잘한 규칙을 무시하고 개발하였습니다.
이 때 사용한 git 전략(전략이라고 하기도 뭐하지만)은 지금 생각해보면 github flow와 비슷한 전략이었습니다.
개발을 굉장히 빠르게 진행했어야 했어야 했기에, 개발이 완료되면 main에 바로 병합하고, 알파와 스테이징 서버는 개발자가 필요로 할때 수시배포 하였습니다.
하지만 런칭을 하고 상용 서버가 열리면서 본격적으로 git 전략을 세워야할 필요성을 느끼게 되었습니다.
계몽의 시대
서비스를 오픈하고 개발자가 늘어나면서 제대로 git 전략을 세우고 적용하자고 의견을 모았습니다. 이 때 우리가 검토한 git 전략은 아래와 같이 가장 유명한 두가지였습니다.
github flow 전략
깃허브에서 강력하게 밀고 있는 깃허브 플로우 전략입니다.
이 전략은 main 브랜치에서 feature 브랜치를 딴 뒤, 개발을 완료하고 바로 main 브랜치에 머지하는 전략입니다.
하지만 해당 전략은
- 우리가 테스트에 사용하는 알파/스테이징 서버 테스트 방법과 맞지 않음
- main에 테스트가 완료되지 않은 feature 브랜치가 머지될 수 있음
등을 이유로 빠르게 반려되었습니다.
git flow 전략
이 전략은
- develop, release 브랜치를 알파/스테이징 테스트용으로 사용할 수 있어 우리의 테스트 방법을 도입할 수 있음
- 브랜치가 많이 나뉘기 때문에 테스트가 완료된 브랜치만 머지할 수 있음
등의 이유로 채택하게 되었습니다.
브랜치 목록
- prod: 상용 서버 배포 브랜치
- main: 기본 브랜치
- staging: 스테이징 서버 배포 브랜치 (QA 테스트용)
- release: Release Candidate 브랜치
- alpha: 알파 서버 배포 브랜치 (개발자 내부 테스트용)
- develop: 개발 브랜치
해당 브랜치들은 다음과 같은 관계를 가집니다.
- develop → alpha
- release → staging
- main → prod
git 전략
- develop에서 feature 브랜치 생성
- feature를 develop에 병합
- develop를 alpha에 병합 → 알파 서버 배포됨 → 개발자 내부 테스트 진행
- develop를 release에 병합
- release를 staging에 병합 → 스테이징 서버 배포됨 → QA 테스트 진행
- release를 main에 병합
- main을 prod에 병합 → 상용 서버 배포됨
이렇게 운영을 해보았을 때 아래와 같은 단점을 발견하게 되었습니다.
단점
- feature 브랜치가 develop에서 따이고, 개발 직후 develop에 병합되기 때문에 발생하는 문제
- develop에서 feature1 브랜치 생성 → 개발 완료 직후 develop에 머지 → develop에서 feature2 브랜치 생성을 하게 되면 feature2는 feature1의 개발 내역을 전부 갖게 됨
- feature1이 버그나 일정으로 지연될 경우 feature2는 손으로 feature1 내역을 제거하거나 (이 경우 나중에 feature1 머지 충돌 발생), feature1이 배포 될 때 까지 지연됨
2. develop 브랜치가 release에 병합되기 때문에 발생하는 문제
- 여러 개발 내역들이 병합되어 올라오기 때문에, feature 브랜치 중 하나라도 QA를 통과하지 못하면 배포가 통째로 지연되게 됨
전략 1차 수정
우선 단점 1번을 제거하기 위해 다음과 같이 수정하였습니다.
- develop에서 feature 브랜치 생성 → main에서 feature 브랜치 생성
상기 Git flow 단점의 1번 문제는 해결되었지만, 2번 문제인 릴리즈 병합으로 인한 배포 지연 문제는 여전히 발생하고 있었습니다.
전략 2차 수정
단점 2번을 제거하기 위해 다음과 같이 수정해서 운영해 보았습니다.
- develop 브랜치 제거
- main에서 feature 브랜치 생성
- feature를 alpha에 PR 및 병합 → 알파 서버 배포됨 → 개발자 내부 테스트 진행
- feature를 releases/<배포날짜>에 병합
- releases/<배포날짜>를 staging에 PR 및 병합 → 스테이징 서버 배포됨 → QA 테스트 진행
- releases/<배포날짜>를 main에 병합
- main을 prod에 PR 및 병합 → 상용 서버 배포됨
배포 날짜를 분리함으로써 이제 2번 문제도 해결되었습니다.
또다른 문제
하지만 이번에는 배포 주기가 문제가 되었습니다.
배포를 주 1회 진행하다보니 배포 사이즈가 커지게 되고, 배포 스트레스가 엄청나게 커지게 되었습니다.
또한 배포 후 잘 동작하는지 확인하는데 많은 시간이 소요되게 되어, 배포날은 다른 작업을 거의 진행하지 못하는 일이 빈번히 발생했습니다.
연관 부서에서도 요청 하루만에 작업 완료 되었음에도 최대 1주일 지연이 되는 문제가 생기기도 했습니다.
현재
생각해보니 main이 releases 와 차이가 없다! 또한 날짜를 정해두고 배포하는것은 배포가 지연되는 순간 브랜치 이름이 안맞는다! 이렇게 된거 releases 브랜치를 없앤다!
releases 브랜치를 없애고 보니 feature 단위로 main에 병합할 수 있게 되었다! 배포 주기도 짧게 가져가자! 얼마나? 수시 배포하자!
브랜치 목록
- prod: 상용 서버 배포 브랜치
- main: 기본 브랜치. 언제든 배포가 가능하도록 유지한다. Release Candidate역할을 한다.
- staging: 스테이징 서버 배포 브랜치 (QA 테스트용)
- alpha: 알파 서버 배포 브랜치 (개발자 내부 테스트용)
git 전략
- main에서 feature 브랜치 생성
- feature를 alpha에 PR 및 병합 → 알파 서버 배포됨 → 개발자 내부 테스트 진행
- feature를 staging에 PR 및 병합 → 스테이징 서버 배포됨 → QA 테스트 진행
- feature를 main에 PR 및 병합
- main을 prod에 PR 및 병합 → 상용 서버 배포됨
처음에는 feature가 main에 병합되는 대로 수시 배포했습니다. 하지만 관리자가 심하면 하루 종일 PR 검토 및 배포만 하게 되는 일이 벌어졌습니다.
그렇다면 수시 배포하지 말고, 배포 주기를 짧게 가져가자!
하루 2회! 단, 핫픽스는 바로 배포한다!
그렇게 급하게 배포할 일은 많지 않고, feature 쌓이는 속도를 보니 오전, 오후 하루 2회로 충분하다!
하지만 금요일 오후 배포는 주말에 대응이 늦어질 수 있으므로 긴급한 수정이 아닐 경우 다음주 월요일로 미룬다!
장점
- 각 단계별 PR이 명확함
- 배포 주기를 짧게 가져갈 수 있어 배포가 길게 지연되지 않음
- 한번 배포할 때 들어가는 기능 단위가 작아 관리자 검토가 용이
단점
- 각 feature당 PR을 3개씩 만들어야 함 (alpha, staging, main)
→ 이 부분은 github action으로 alpha에만 PR을 날리면 나머지 PR을 자동으로 만들어지도록 설정했습니다.
- feature 브랜치는 항상 alpha에 먼저 병합되므로 브랜치 목록에서 보면 항상 merged 상태가 된다. 따라서 PR 목록을 보지 않고서는 어느 단계까지 배포되었는지 알 수 없습니다.
→ 이부분은 각 개발자가 자신의 브랜치를 책임지고 관리하도록 하였습니다.
향후 개선점
상용 배포를 마치고 나면 alpha, staging 서버를 손으로 main과 동일하게 갱신해야하는 문제가 발생되었습니다.
이 역시 github action으로 빠른 시일내로 자동화할 예정입니다.
마치며
어떠한 git 전략을 사용해도 단점이 없는 전략이 없기 때문에, 무엇이 정답인지 계속 고민하게 되었던 것 같습니다.
물론 앞으로 개발팀 인원이 더 늘어난다면 새로운 단점이 부각될 것이고, 그때의 우리는 더 좋은 전략을 찾고 변화할 예정입니다.
읽어주셔서 감사합니다.
written by Dante (Hosup Um)
email: hs.uhm@fitpet.co.kr