Search

App에서 MAJOR.MINOR.PATCH 버전의 기준은 어떻게 잡을까요? : 유의적 버전(Semantic Versioning)

🫡
"유의적 버전(Semantic Versioning)",
"MAJOR.MINOR.PATCH" 같은 표현, 많이 들어보셨죠?
무슨 말인진 알겠는데 App 환경에는 맞지 않아
적당히 타협해서 적용하고 계시진 않나요?
App에서 MAJOR.MINOR.PATCH 기준은 어떻게 잡을까요?
제 나름의 시각으로 해석해봤습니다.

MAJOR.MINOR.PATCH 기준은 어떻게 잡을까?

아무래도 주,부,수 라는 표현보다 MAJOR.MINOR.PATCH 라는 표현이 더 이해하기 편할 것 같습니다.
앞선 문서를 읽고 나서 곧바로 개발중인 서비스에 적용하려니 물음표가 자꾸 생깁니다.
해당 문서가 서버 API 기준으로 작성된 문서다보니
앱 서비스의 관점에서 해석하면 맞지 않는 경우들이 더러 있었습니다.
앱 입장에서 현실에 맞게 하나씩 짚어보겠습니다.

1. 기존 버전과 호환되지 않게 API가 바뀌면 “주(主) 버전”을 올리고,

앱에서 ‘기존 버전과 호환되지 않는’ 경우라 함은 업데이트 후
기존 버전이 더이상 동작하지 않게 되는 것을 의미합니다.
하지만 업데이트를 하면서 기존 버전과 호환성을 한순간에 끊어버리는 경우는 잘 오지 않죠.
그래서 보통 Migration 정책을 준비해놓고 서버와 연계해 이전 버전을 유지하며,
사용자들에게는 업데이트를 ‘권장’ 하는 방식으로 최신 버전 설치를 유도해
점진적으로 기존 버전과의 호환성을 줄여 나갑니다.
그리곤 일정 수준이 되면 ‘강제’ 업데이트를 통해 기존 버전과의 연결을 끊어냅니다.
그렇다면 위 흐름에서 ‘MAJOR’ 버전을 올리는 건 어느 때일까요?
Migration을 시작하는 시점?
모든 호환성이 제거되는 시점?
이렇게 기존버전과의 호환만 생각한다면
앱에서는 딱 맞아떨어지지 않는 부분이 생깁니다.
(영원히? 1.x.x 에 머무르게 될지도 모르죠 )
그럼 언제 MAJOR 버전을 올릴까요?
‘이전 버전과 구분되는 확연한 변화점이 생길 때’ 라고 보면 됩니다.
기준이 애매하신가요? 네 그렇죠. 제가 뭐 기준을 만드는 사람은 아니…
‘이전 버전과 구분되는’의 기준은 꼭 코드 상의 변화라기보다는 서비스의 변화, 디자인의 변화인 경우를 모두 포함합니다.
서비스를 관통하는 어떤 기능이 생겼거나,
디자인이 전면 개편되었거나,
코드를 전면적으로 리팩토링 했다던가 하는 경우가 포함될 수 있습니다.
물론 마케팅에 버전을 사용한다면 코드 변화로 버전을 올리는데에는 제약이 있을 수 있겠지만,
대부분의 경우 서비스의 관점에서 이용자의 입장에서 판단해 올린다고 이해하시면 됩니다.

2. 기존 버전과 호환되면서 새로운 기능을 추가할 때는 “부(部) 버전”을 올리고,

아마 첫번째보다 이 두번째 MINOR 버전의 숫자가 제일 자주 변경되게 될텐데요.
MINOR 버전을 올리는 기준은 사실 더 쉽습니다.
바로 ‘PATCH 업데이트가 아닐 때’ 입니다.
그럼 PATCH 업데이트의 기준만 정하면 MINOR의 기준이 생기는거겠죠?
먼저 PATCH 업데이트 기준을 알아보고 다시 설명하겠습니다.

3. 기존 버전과 호환되면서 버그를 수정한 것이라면 “수(修) 버전”을 올린다.

PATCH 업데이트의 핵심은 ‘버그 수정’ 입니다.
여기서 자칫 혼동하기 쉬운 점이 있는데
바로 ‘기획 수정’입니다.
기획이 수정되는 것과 버그를 수정하는 것은 엄연히 다른 개념으로 접근해야 합니다.
먼저 기획을 통해 어떤 기능이 추가되어 들어갔다면,
MINOR 버전을 올리는 데에는 아무 이견이 없을 겁니다.
하지만 이미 배포된 앱에 대해 기획적인 사항이 수정된다면 어떻게 해야 할까요?
아래 사례들을 보고, 해당 수정사항이 기능 수정인지 버그 수정인지 판단해보세요.
리워드 광고가 너무 긴거 같아요. 광고의 타입을 교체해주세요.
문구 표현이 너무 딱딱한거 같아 바꿔봤어요. 교체 적용해주세요.
공지사항 아이콘이 눈에 잘 안띄는거 같아요. 이미지를 교체해주세요.
명확하게 나눌 수 있으셨나요?
이런 사례들의 공통점이 있습니다. 바로 사소해서 수정이 어렵지 않다는 점인데요.

MINOR와 PATCH를 나누는 기준은

수정되는 코드의 양에 있는 것이 아니라, 서비스의 변화 여부에 있습니다.
사소하든 아니든 서비스의 변화가 생겼다면, 이는 관리해야 할 대상으로 봐야 합니다.
특히 또 iOS는, 함께 고려되어야 할 Andriod라는 친구가 있죠. (Window, MAC 친구도 있어요.)
만약 위 사례들의 수정을 PATCH로 하게 된다면, 여러 플랫폼이 같은 버전을 맞추기 어려워지고,
같은 버전을 맞추지 못한다면, 히스토리 파악에 어려움을 격게 됩니다.
언제 바꿨는지 알려면 버전 문서를 다 뒤져봐야 하는거죠.
(ex> iOS는 1.2.3에 수정했는데 Android는 1.2.1 에 수정한 경우)

그렇다면 이 PATCH는 어떻게 올리느냐

정말 버그 수정에만 쓰면 됩니다.
각 플랫폼별로 버그를 수정하든 리팩토링을 통해 퍼포먼스를 개선하든, 심지어 핫픽스를 할 때까지
협업이 아닌 각 플랫폼의 사정에 따라 숫자를 관리합니다.
MINOR 업데이트가 안정화 되가는 PATCH 업데이트라고 생각하면 됩니다.
반대로 기획, 디자인에서 나오는 버그도 있습니다.
아까 사례 중 앱 내 사용되는 문구의 변경이 기획 의도가 아닌
오타로 인한 것이라면 이는 PATCH로 해결되어도 무방합니다.
이때 기준은 ‘추적할 필요가 있는가’ 에 있게 되겠네요.
플랫폼 별로 같은 버전을 공유해 함께 수정될 내용인지에 판단에 따라 결정하면 될 것 같아요.

4. iOS는 빌드 번호도 쓸 수 있습니다.

AppstoreConnect! 이 녀석은 4자리 버전을 지원하지 않습니다.
하지만 대신 하나 더 쓸 수 있는 숫자가 있죠. 바로 빌드 번호입니다.
한 버전으로 여러번 패키징하게 되는건 일상일테니 따로 설명하지 않아도 될테고,
이 숫자를 버전에 상관없이 순증시킨다거나
빌드하는 날짜와 횟수를 적는 스크립트를 넣어 사용하는 방식으로
버전을 보조하는 역할을 할 수 있습니다.

여러번 강조하고 싶은 원칙

아마 여기까지 읽으셨으면 대충 감이 오실껍니다.
그래도 사례는 무궁무진하게 많고 그때 마다 헷갈리는 경우도 많을텐데요.
몇가지 강조하고 싶은 주제들이 있습니다.

버전 관리는 우리가 이해하기 편하려고 하는 것이다.

예전에는 버전 업데이트를 마케팅에 활용하던 시절이 분명 있었습니다만,
요즘은 이 버전의 숫자가 사용자에게 큰 의미가 없습니다.
앱은 수시로 매일매일 업데이트 되며,
심지어 그 업데이트도 자동으로 되니 항상 최신버전을 쓰는데 전혀 문제가 없죠.
오히려 낮은 버전으로 이동이 불가능하기까지 합니다.
굳이 버전을 마케팅에 활용하고자 한다 해도 MAJOR 버전이면 충분합니다.
굿노트나 페럴럴즈가 매년 또는 주기적으로 새로운 버전을 내놓는 대표적인 서비스들인데,
그들이 “우리가 2.5에서 2.6버전으로 올라가며 서비스가 새로워졌습니다!” 라고 홍보하지 않듯이
마케팅은 MAJOR 버전으로 하는게 올바른 접근이라고 생각합니다.
우리가 지금 이야기 하고 있는 버전은 우리가 함께 일할때 효율적인 커뮤니케이션을 위한 숫자입니다.

버전 1.234.5는 아무 문제가 없다… 하지만

1.2.3 이라는 버전이 업데이트되고 업데이트 되어 1.234.5이 된들 아무 문제가 생기지 않습니다.
유저가 이 숫자를 보고 비난하거나 조롱하지도 않을 껍니다.
(아마) 동료들과 기능을 이해하는데에도 큰 문제는 없을 껍니다.
하지만 위에서 기술한 기준들을 생각해보면,
1.2.x와 1.200.x는 여전히 비슷하고 같은 앱이라고 할 수 있는가,
약 200번의 업데이트를 통해 전혀 다른 앱이 되진 않았는가 하는 것들인데요.
하지만 이 200번의 업데이트 사이사이에 각 버전들은
그 전버전과의 차이가 적어 MAJOR 버전을 올리기가 애매했을겁니다.
그럼 언제 2.x로 올리면 되냐구요?
‘아무 때나’ 올려도 됩니다. 어차피 우리가 함께 일하기 위해 사용하는 버전이잖아요.
모두가 함께 “현재 버전은 1.0 과 너무 많이 달라졌어” 에 공감한다면 그때가 2.0으로 올려야 할 때입니다.

마무리

버전을 관리하는 방법은 다양하고, 사람마다 자신(만)이 이해하기 쉬운 기준들이 있을 수 있습니다.
이 글도 제가 그동안 쌓인 경험에서 오는 제가 이해하기 쉬운 기준들 일 수 있습니다.
하지만 결국 iOS는 AppstoreConnect의 강제성 때문에 3자리 버전을 벗어나긴 어렵고,
유명하고 훌륭하신 분이 좋은 기준도 제시해주셨습니다.
여러분들도 이 글을 참고 삼아 본인의 업무 환경에 맞게 사용하시면 분명 많은 도움이 될 거라 믿습니다.
혹 좋은 예시나 방법이 있다면 댓글 달아주세요.
아 댓글 아직 못다네요. 작업해야겠다.