2010년, 제즈 험블과 데이비드 팔리의 Continuous Delivery가 출판되었습니다.
그리고 같은 해에 Git Flow가 빈센트 드리슨에 의해 제안되었습니다.
2022년 1월 GOTO Conference 채널에 업로드 된 영상에서
데이비드 팔리는 Git Flow가 CI/CD 에는 어울리지 않는다고 이야기합니다.
해당 영상의 내용을 요약하며 왜 그러한지 이해한 내용을 기록해봅니다.
David Farley 가 이야기하는 CI
어.. CI 그렇게 하는 거 아닌데..
추측(guessing)이 아닌 확인(checking)을 해야 한다
Dave는 여러 개발자들이 함께 일하고 있는 시스템의 상태에 대해
공유된, 정확한 관점을 유지하고 배포하는 것을 CI 라고 이야기합니다.
이러한 정의에 입각해서 Dave는 다음과 같이 논지를 확장시킵니다.
- CI는 여러 개발자들이 협업 대상물의 정확한 상태를 공유하고 배포하는 것이다.
- 따라서 우리가 만들고 있는 코드의 변화가 병합되어서도 잘 동작하리라 추측해선 안된다.
- 하루에도 수차례 지속적으로 빈번하게 병합되어서도 잘 동작한다는 것을 확인해야 한다.
단 하나의 관심사
여러 개발자들이 협업 대상물의 상태를 최대한 정확하게 공유하려면 어떻게 해야 할까요?
수시로 통합하고, 수시로 변경에 대해 확인하는 것은 물론, 관심사가 분산되어선 안됩니다.
즉, 단 하나의 브랜치를 운영해야 한다는 것입니다.
C2 Wiki 에서는 CI 의 전제 조건을 다음과 같이 소개합니다.
CI의 근본적인 가정은 관심을 가지는 버전은 단 하나라는 것이다.
그리고 그것은 현재 버전을 의미한다.
다시 말하자면, 단 하나로 존재하는 현재의 버전,
그것에만 모두가 관심을 가진다면 이에 대한 변화를 수시로 확인하고
작업 중간중간에 자신의 결과물을 반영하고 병합 해도 잘 동작하는지 확인함으로써
여러 개발자들이 정확한 상태를 공유할 수 있게 된다는 것입니다.
그리고 이 논지는 Git Flow 와 완전히 배치됩니다.
관심을 가지는 현재 버전은 하나, main 브랜치
앞서 단 하나의 관심사, 단 하나의 현재 버전 이라는 표현을 썼는데요,
이를 제 언어로 해석해본다면 이는 곧 main 브랜치를 의미합니다.
Git Flow는 develop, feature, release, hotfix 등의 브랜치를 추가로 사용하지만,
이 모두가 결국은 main 브랜치를 통한 운영 배포를 더 수월하게 하기 위함입니다.
즉, 결국 관심사는 main 브랜치를 통한 서비스의 전달에 있는 것이고,
다른 브랜치들은 main 브랜치를 위한 보조적인 역할을 수행할 뿐이라는 겁니다.
Git Flow 를 공부하는 과정에서는
이렇게 역할을 분리해서 브랜치를 다루게 되면 관리 포인트가 늘어나긴 하지만
이에 따른 안정성에 대해 장점과 편안함을 느꼈습니다.
그런데 Dave Farley의 관점을 접하고 나니
Git Flow의 여러 브랜치들이 결국은 main 브랜치를 어떻게 하면 더 안정적으로
더 효과적으로 업데이트 해나갈 것인가를 위해 고안된 장치들이란 걸 알게 됐습니다.
Git Flow는 피드백이 늦다
Dave Farley 가 이야기하는 CI/CD 는 최소 하루에 한번 pull, merge를 수행하고
가능하다면 이를 하루에도 여러번 수행해야 합니다.
그렇게 해야 하는 이유는
우리가 관심을 가지는 단 하나의 브랜치는 main 브랜치이기 때문에,
현재 개발중인 기능이 완료되지 않았더라도 중간중간 병합하고 테스트하여
병합 후에도 정상적으로 동작하는지 추측이 아닌 확인을 해야 하기 때문입니다.
반면 Git Flow 전략은 어떤가요?
develop 브랜치로부터 기능 개발을 할 때마다 feature 브랜치를 분기합니다.
그리고 이 브랜치에서 개발을 진행하고,
기능 개발이 완료되면 그제서야 develop 브랜치에 병합합니다.
병합한 뒤에는 다시 한번 테스트를 거쳐야 합니다.
팀 프로젝트에서 Git Flow 전략을 선택해서 이 지점은 이미 경험하고 있습니다.
백엔드 4명의 크루가 2명씩 2개의 페어로 나눠져 서로 다른 작업을 진행하고 있습니다.
따라서 각각 feature/task-1, feature/task-2 와 같은 별도의 feature 브랜치에서 구현중이죠.
그러다보니 중간중간 상대방의 구현과 겹치는 순간이 발생하여
동료에게 구현중인 코드에 대해 의사소통해야 하는 비용이 발생하고 있습니다.
분명 기능적으로 분리가 되었음에도 완전히 분리되기에는 어려움이 있는 것 같습니다.
이처럼 Git Flow는 피드백이 느리다는 단점이 있습니다.
내가 개발중인 feature 브랜치가 병합해도 잘 되겠지,
다른 feature 브랜치와 충돌 나지 않겠지 와 같은 낙관적 가정을 전제로 개발을 진행합니다.
그러다가 개발이 완료되면 그제서야 병합을 진행하고,
이 때 혹시 잘못 개발하고 있었다는 것을 알게 된다면 이때는 이미 많은 시간을 소비한 뒤 일 겁니다.
기능 개발이 완료되지 않았더라도,
중간중간 수시로 하나의 공통된 브랜치에 병합을 하며 빠르게 피드백을 받는다면,
다른 동료 개발자들의 코드도 수시로 함께 확인하며 더 수월하게 작업할 수도 있고
혹여 잘못 개발하고 있었더라도 이에 대해 빠르게 대처할 수 있을 것입니다.
이 지점이 Dave Farley 가 이야기하는 추측하지 말고 확인해야 한다 로 이해됩니다.
Git Flow는 변화를 숨긴다
Git Flow의 여러 브랜치들이 존재하는 이유는
여러 개발자가 원활히 동시에 개발을 진행할 수 있게 하기 위함으로 보이기도 하지만,
사실은 안정성을 위해 속도를 일부 양보하는 것입니다.
그리고 이처럼 안정성을 위해 속도를 양보해야만 하는 이유는
feature 브랜치들이 개별적으로 진행되며 공유되지 않기 때문에,
이것이 병합되었을 때 안전한지 확신할 수 없기 때문입니다.
병합 후 추가적인 검증이 필요한 것이죠.
이는 다시 말하면 최종 관심사인 main에 대한 변화를 만들어내기 위한 여정 속에,
서로의 feature 브랜치의 존재로 인해 서로의 변화가 격리되고 감춰져버린다는 것입니다.
Dave Farley는 자신의 작업 방식을 다음과 같이 소개합니다.
- main 을 로컬에 클론
- 개발을 진행
- 테스트가 통과할 때마다 커밋을 쪼개서 자주 수행
- 즉시 push
모든 협업하는 개발자들이 이렇게 수시로 main 브랜치에 직접 push를 한다면
자동적으로 하루에도 수차례 pull을 받을 수밖에 없을 것입니다.
그리고 최초에 Dave Farley가 이야기한 CI 정의에도 가까워질테죠.
함께 일하는 시스템에 대해 정확하게 공유된 관점을 유지하고 배포하는 것 말입니다.
이렇게 일하게 된다면 안전감을 느끼게 될 수 있습니다.
지금 내가 만들고 있는 변경들이 releasable 하다, 배포되어도 안전하다 라고 말이죠.
나도 점진적으로 변화를 만들고 있지만, 거의 실시간으로 다른 개발자들의 변경도
내가 함께 확인하며 병합된 상태에서 빠른 피드백을 받을 수 있을 테니까요.
Github Flow 조차 CI/CD 로 인정하기 어려운 이유
데이빗 팔리는 빈센트 드리슨이 Git Flow의 최초 제안 이후 10년이 지나
자신의 포스팅에 코멘트를 추가한 내용에 대해 언급합니다.
CI/CD 를 하고 있다면 Github Flow 처럼 보다 단순한 모델을 사용하라는 코멘트였는데요,
데이빗 팔리는 이에 대해 용기있는 행동이고 고마움을 표시하지만 여전히 만족하진 않습니다.
데이빗 팔리의 시선에서는 Git Flow, Github Flow 모두
feature branch strategy 라는 범주에 속하기 때문입니다.
개별 기능 개발이 완료될 때까지 병합을 미루고
서로의 변경을 숨기고 격리시키고, 통합 시점의 비용이 증가한다는 이야기입니다.
그리고 이러한 일련의 단점들이 발생하는 이유가
지금 일으키고 있는 변화가 얼마나 안전하다고 확신하는지의 문제라고 지적합니다.
개발자들이 CI를 불안해하는 이유
기능 단위의 개발이 완료되기 이전에 변화를 노출해야 하기 때문에
개발자들이 CI를 불안하게 여긴다 라는 게 데이빗 팔리의 설명입니다.
사실 이와 같은 지적은 모든 개발자 뿐만 아니라
다른 영역에 있는 대다수의 사람들에게도 적용될 수 있을 것 같습니다.
아주 뛰어난 고수가 아니고서야
자신의 과정이 낱낱이 드러나는데에 있어 크기에 차이는 있을지언정
다소간 부끄러움이나 숨기고 싶은 심정이 있는 것은 자연스럽기 때문입니다.
그래서 데이빗 팔리는 이 지점에 대해
일하는 방식 자체에 대한 변화를 주장합니다.
기능 개발이라는 하나의 작업 단위의 프로세스 조차도
보다 점진적으로 진행해보는 것이 어떻겠냐는 것입니다.
Git Flow 가 CI/CD를 막는다 라는 주장과는 별개로
하나의 기능 개발 프로세스 조차 점진적으로 진행하라는 이 지점은
상당히 매력적인 제안으로 들립니다.
워터폴에서 애자일로 개발 프로세스 흐름이 변경된 이유도
보다 빠른 피드백을 통해 더 나은 결과물을 더 빨리 고객에게 전달해서
더 큰 부가가치를 창출하기 위함으로 이해하고 있는데요,
보다 가까이 관찰하면 하나의 기능 개발 단위 조차도
더욱 세세하게 나누어서 진행함으로써
개발자들간에 빠른 피드백을 주고 받는 것이 CI/CD 인 것인가 하는 생각이 듭니다.
요약
- Git Flow, Github Flow와 같은 feature 브랜치 전략을 사용할 경우,
개발 완료 시점이 되어서야 병합하고 피드백을 받게 된다. - 이는 병합 시점에 잘 동작하리라는 추측 기반 작업인데,
이러한 추측이 곧 변화를 감추고 격리함으로써 통합 비용을 증가시킨다. - 통합 비용 중 하나가 통합 이후 추가 검증이 필요하다는 지점인데
이는 변화가 격리되어 있기 때문에 통합 후 releasable 하다고 느낄 수 없기 때문이다. - 어떤 전략을 사용하던 최종적인 관심사는 main 브랜치를 통해 고객에게 전달되는 서비스 아닌가
- Git Flow는 변화를 격리시키고 감춤으로써 발생하는
불안감에 대한 대가로 속도를 늦춘 것이다. - CI/CD는 추측이 아니라 수시로 확인을 하면서 작업을 함으로써 빠른 피드백을 가능하게 한다.
- 즉 releasable 하다는 느낌을 받으며 하나의 작업 단위도 점진적으로 진행한다.
개인 의견
- 진정한 CI/CD를 제대로 구사하는 개발 조직은 정말 소수일 것 같습니다.
- 이상적으로는 CI/CD 를 수행하는 것이 장점이 있을 것 같습니다만
정말 단 하나의 관심있는 브랜치만을 사용하는 것이 충분히 안전한지 의문이 듭니다. - 개발자 외에 QA의 역할이 추가된다거나,
개발자에게 개발서버에 대한 자유로운 배포, 롤백 권한을 준다거나
하는 상황을 고려했을 때 Git Flow의 모델이 안정적으로 느껴집니다. - 다만 데이빗 팔리의 의견을 통해 Git Flow가 취하는 장점 대신에
어떤 부분을 다소 양보하고 있는지에 대해선 알 수 있었습니다.
학습 출처
'우아한테크코스 4기' 카테고리의 다른 글
IntelliJ 플러그인으로 Co-authored-by 설정하기 (0) | 2022.07.19 |
---|---|
Sign in with Slack 으로 워크스페이스 내부 구성원 식별하기 (0) | 2022.07.15 |
🥄 Git Flow 한 스푼 (0) | 2022.07.14 |
아이디어 매몰 주의 - (인지적 구두쇠, 기억 편집) (0) | 2022.07.09 |
📖 배민다움을 읽었습니다 (0) | 2022.07.06 |