시맨틱 버저닝
Semantic Versioning
시맨틱 버저닝이란?
- 버전을 주.부.수로 매김
- 숫자로 변화 성격 파악
- 호환성 관리
시맨틱 버저닝이 실제로 바꾸는 것은 업데이트 판단을 누가 하느냐입니다. 규칙이 없으면 릴리스 노트를 사람이 전부 읽고 결정해야 하지만, 규칙이 있으면 패키지 매니저가 '부 버전까지는 자동으로 올리고 주 버전은 건드리지 마라'는 지시를 기계적으로 수행합니다. package.json의 ^1.4.0, 파이썬의 ~=1.4 같은 표기가 그 지시문입니다. 사람의 확인 작업이 도구의 설정값으로 옮겨간다는 점이 핵심이고, 그래서 의존성이 200~300개인 프로젝트도 주 버전이 바뀐 것만 사람이 검토하는 방식으로 굴러갑니다.
세부 조건에는 실무자가 자주 놓치는 예외가 있습니다. 0.y.z 구간은 규칙의 보호를 받지 못해, 공식 규격도 '0.x에서는 언제든 호환이 깨질 수 있다'고 명시합니다. 1.0.0을 찍는 순간부터 공개 API가 고정되는 셈입니다. 1.0.0-beta.2처럼 하이픈 뒤에 붙는 프리릴리스는 정식 1.0.0보다 낮은 버전으로 취급되고, 플러스 기호 뒤의 빌드 메타데이터는 비교에서 아예 무시됩니다. 우분투 24.04처럼 날짜를 버전으로 쓰는 CalVer와는 목적이 다르니 한 조직 안에서 섞어 쓰면 혼란만 커집니다.
현장에서 가장 흔한 오해는 버전 숫자를 보장으로 믿는 것입니다. 숫자는 배포자가 스스로 매기는 선언일 뿐 검증된 사실이 아닙니다. 실제로 패치 버전이라며 설정 기본값을 바꿔 넣는 라이브러리가 적지 않고, 사내 팀도 '주 버전을 올리면 다른 팀이 싫어한다'는 이유로 호환 깨지는 변경을 부 버전에 숨기곤 합니다. 여기에 lock 파일을 커밋하지 않으면 같은 설치 명령이 개발자 PC와 운영 서버에서 다른 결과를 내고, 장애 원인을 찾는 데만 며칠이 날아갑니다.
톰 프레스턴워너(GitHub 공동창업자)가 정리한 규격(semver.org)으로, 오픈소스 생태계의 사실상 표준이 됐습니다.
가상의 사례로 살펴보겠습니다. 임직원 140명 규모의 물류 SaaS를 운영하는 A사는 지난해 4분기에만 배포 직후 장애를 세 번 겪었습니다. 원인을 추적해 보니 세 건 모두 외부 라이브러리 자동 업데이트에서 시작됐고, 그중 두 건은 버전 맨 뒷자리만 바뀐 '버그 수정'이었습니다.
- 백엔드 리더 김 책임이 한 달치 배포 로그를 뒤져 보니 자동으로 올라간 패키지가 47개였고, lock 파일은 저장소에 커밋조차 되어 있지 않았습니다.
- CTO가 '뒷자리만 올랐는데 왜 서비스가 죽냐'고 묻자, 김 책임은 인증 라이브러리 0.9.3에서 0.9.4로 가며 토큰 만료 기본값이 24시간에서 1시간으로 바뀐 커밋을 화면에 띄웠습니다.
- 팀은 0.x 패키지는 버전을 통째로 고정하고, 캐럿 범위는 1.0.0 이상에만 쓰고, lock 파일은 예외 없이 커밋하는 세 줄짜리 규칙을 저장소 README 맨 위에 붙였습니다.
- 사내 공통 모듈 12개에도 같은 기준을 적용해, API 응답 필드를 하나라도 지우면 주 버전을 올린다는 항목을 코드 리뷰 체크리스트에 넣었습니다. 첫 달에 정산 모듈이 2.7.0에서 3.0.0으로 올라갔습니다.
- 반년 뒤 배포 직후 장애는 분기 3건에서 0건이 됐고, 업데이트 PR 하나를 검토하는 시간도 평균 40분에서 10분으로 줄었습니다.