CI가 아예 존재하는 이유
CI가 당연해지기 전에는 소프트웨어를 릴리스 주기에 맞춰 출시했어. 팀이 기능 브랜치에서 몇 주, 심하면 몇 달씩 일했지. 주기가 끝날 때 모든 브랜치를 한꺼번에 트렁크로 병합하려 들었어. 이걸 통합 지옥이라고 불렀어.
통합 지옥이 실제로 어떤 꼴이었냐면:
- 두 엔지니어가 같은 함수를 서로 호환되지 않는 방식으로 리팩터링했어. 병합하는 날까지 둘 다 몰랐지.
- 한 팀이 데이터베이스 스키마를 바꿔서 다른 팀 브랜치의 쿼리를 망가뜨렸어. 그 브랜치는 3주 동안 아무도 안 만졌거든.
- 모든 브랜치를 합쳐야만 빌드가 깨진다는 걸 알 수 있었어. 각 브랜치는 고립된 상태에서는 통과했거든.
- 릴리스가 기능 때문에 늦어진 게 아니라, 그냥 병합하는 데 2주나 써서 늦어졌어.
CI가 이걸 어떻게 해결하냐
CI는 마지막에 한 번에 거대하게 병합하는 걸, 수백 번의 작은 병합으로 쪼개버려. 각 작은 병합이 충돌을 바로 드러내주거든. 맥락이 아직 생생하고 위험 부담도 기능 하나뿐일 때 말이야. 충돌 비용이 기하급수가 아니라 선형으로 유지돼. 병합 작업이 이미 끝나 있으니 릴리스 날짜도 예측할 수 있어.
옛날이 얼마나 나빴는지 떠올리는 향수가 아니야. 통합 지옥은 오늘도 일어나. 오래된 브랜치가 이탈하도록 방치하는 팀, 릴리스 브랜치에서만 CI를 돌리는 팀, 급한 커밋 때 CI를 우회하는 팀. 원칙이 빠진 자리에선 똑같은 패턴이 반복돼.