시맨틱 버저닝
Semantic Versioning
방법
버전 번호를 세 자리로 나눠 어느 자리가 올랐는지로 변경의 성격을 알려 주는 규칙입니다.
등장 배경
남이 만든 코드를 가져다 쓰면 그 코드가 새 버전을 낼 때마다 판단이 필요합니다. 올려도 되는지, 올리면 우리 코드가 깨지는지입니다. 버전 번호가 순서를 나타내기만 하면 이 판단을 할 수 없습니다. 2.3에서 2.4로 올라간 것이 오타 수정인지 함수 이름이 바뀐 것인지 번호만 봐서는 갈리지 않습니다.
페이지덱도 그 자리에 있었습니다. 태오가 문서 편집기에 쓰는 외부 코드를 한 단계 올렸는데 붙여넣기 기능이 멈췄습니다. 번호는 한 자리만 올랐고 안내문에는 개선이라고 적혀 있었습니다. 실제로는 함수 하나가 없어진 변경이었습니다. 원인을 찾는 데 반나절이 들었고, 그 뒤로 태오는 어떤 버전도 확인 없이 올리지 않게 됐습니다. 그것이 안전하기는 하지만 갱신을 아예 안 하게 만드는 쪽으로 흘렀습니다.
시맨틱 버저닝은 번호 자체가 판단 재료가 되게 만든 규칙입니다. 어느 자리가 올랐는지만 보면 확인해야 하는지 그냥 올려도 되는지가 정해집니다.
사용 절차
번호를 점으로 나눈 세 자리로 적고, 변경의 성격에 따라 올릴 자리를 고릅니다. 2.4.1 이라면 앞자리가 2, 가운데가 4, 끝자리가 1입니다.
- 끝자리를 올리는 경우 — 고치기만 한 변경입니다. 오류를 바로잡았고 쓰는 방법은 그대로입니다. 2.4.1에서 2.4.2가 됩니다. 쓰는 쪽은 확인 없이 올려도 됩니다. 고쳤다고 적혀 있어도 그 오류에 기대 짜 둔 코드가 있으면 깨질 수 있습니다.
- 가운데를 올리는 경우 — 기능을 더한 변경입니다. 새 함수나 새 옵션이 생겼지만 기존 사용법은 그대로 돕니다. 2.4.2에서 2.5.0이 됩니다. 이때 끝자리는 0으로 되돌립니다.
- 앞자리를 올리는 경우 — 기존 사용법을 깨뜨리는 변경입니다. 함수가 없어졌거나 넘기는 값의 형태가 달라졌습니다. 2.5.0에서 3.0.0이 되고 뒤 두 자리는 0으로 돌아갑니다. 쓰는 쪽은 자기 코드를 고쳐야 합니다.
- 정식 출시 전 — 앞자리가 0인 구간은 규칙이 느슨합니다. 0.x 에서는 언제든 깨지는 변경이 올 수 있다고 보는 것이 관행입니다. 그래서 0.x 코드를 운영 환경에 쓸 때는 버전을 고정해 둡니다.
- 표시와 공지 — 올린 자리와 함께 무엇이 달라졌는지 적은 목록을 냅니다. 앞자리를 올렸다면 옮겨 가는 방법까지 함께 적습니다. 목록 없이 번호만 올리면 쓰는 쪽은 코드를 직접 뜯어 봐야 합니다. 번호를 붙인 시점은 Git 같은 도구에 표시로 남깁니다. 분산형으로 변경 이력을 관리하는 도구입니다.
가져다 쓰는 쪽에서는 이 규칙을 이용해 허용 범위를 적어 둡니다. 앞자리는 고정하고 뒤 두 자리는 자동으로 올라가게 두는 설정이 가장 흔합니다. 이렇게 두면 오류 수정과 기능 추가는 저절로 들어오고, 깨지는 변경은 사람이 결정할 때만 들어옵니다. 이 설정은 지속적 통합이 함께 걸려 있을 때만 안전합니다. 변경을 자주 합치고 자동으로 검증하는 방식입니다.
적합한 상황과 한계
잘 맞는 자리는 남이 가져다 쓰는 코드입니다. 라이브러리, 공개한 연동 규격, 다른 팀이 호출하는 내부 서비스가 그렇습니다. 쓰는 쪽과 만드는 쪽이 다르고 그 사이에 대화가 없을 때 번호가 대화를 대신합니다.
한계는 넷입니다.
- 깨지는 변경인지 판단이 갈립니다. 만드는 쪽에서는 사소한 정리인데 쓰는 쪽에서는 깨지는 경우가 있습니다. 오류 메시지 문구를 바꿨는데 누군가 그 문구로 조건을 걸어 두었던 식입니다. 이 판단을 보수적으로 하지 않으면 규칙이 있어도 신뢰가 쌓이지 않아서, 애매하면 앞자리를 올리는 쪽으로 기웁니다.
- 사용자가 직접 쓰는 제품에는 잘 맞지 않습니다. 웹 서비스는 쓰는 사람이 버전을 고르지 않으므로 앞자리를 올리는 개념이 성립하지 않습니다. 이런 제품은 날짜를 번호로 쓰거나 번호를 밖에 알리지 않습니다.
- 앞자리가 자주 올라가면 의미가 옅어집니다. 반년에 세 번 앞자리가 올라가는 코드는 쓰는 쪽에서 갱신을 포기합니다. 깨뜨릴 변경을 모아 한 번에 내보내는 쪽이 낫습니다.
- 번호가 품질을 말하지 않습니다. 1.0.0이 완성을 뜻하지도 않고 5.0.0이 더 성숙함을 뜻하지도 않습니다. 세 자리는 변경의 성격만 나타냅니다.
규칙을 지키는 일은 사람 손에 달려 있습니다. 그래서 어느 자리를 올릴지 정하는 기준을 문서로 적어 두고, 앞자리를 올리는 결정은 혼자 하지 않게 만드는 팀이 많습니다.
실무 용례
"이번 변경 앞자리 올려야 합니다. 함수 하나를 없애니까요."
기존 사용법이 깨지므로 앞자리라는 판단입니다.
"가운데만 올랐으니까 그냥 올려도 됩니다."
번호를 보고 확인 없이 갱신하겠다는 뜻입니다.
"0.x 짜리를 운영에 쓰려면 버전을 고정해 두죠."
정식 출시 전 구간은 규칙이 느슨하다는 지적입니다.
페이지덱은 다른 팀이 호출하는 내부 서비스에 이 규칙을 붙였습니다. 태오가 어느 자리를 올릴지 판단하는 기준을 한 장으로 적고, 앞자리를 올릴 때는 다른 팀에 2주 전에 알리는 절차를 함께 만들었습니다.
그 뒤로 갱신 때문에 멈추는 일이 줄었습니다. 대신 앞자리를 올릴 결정이 전보다 어려워졌습니다. 2주 전 공지를 만들어야 하니 정리하고 싶은 변경을 모아 두게 됐고, 반년에 한 번 큰 버전을 내는 방식으로 굳었습니다. 쓰는 쪽에는 편했지만 정리하고 싶은 것을 반년씩 참는 부담이 남았습니다.
흔한 오해
번호가 제품의 성숙도를 말한다고 보는 경우가 가장 많습니다. 1.0이 완성이고 숫자가 클수록 좋은 것처럼 읽힙니다. 그런데 이 규칙에서 앞자리는 깨뜨린 횟수에 가깝습니다. 자주 깨뜨린 코드가 번호가 큽니다. 성숙도로 읽으면 앞자리를 올리기 꺼려지고, 꺼리는 팀은 깨지는 변경을 가운데 자리에 숨겨 내보냅니다. 그 순간 이 규칙은 아무 정보도 주지 않는 번호가 됩니다.
끝자리만 올랐으면 안전하다고 믿는 것도 흔합니다. 규칙상 맞는 말이라 그렇게 됩니다. 하지만 규칙을 지키는 것은 사람이고, 실수로 깨지는 변경이 끝자리에 섞여 나가는 일이 있습니다. 그래서 자동으로 올리는 설정을 쓰더라도 테스트가 함께 돌아야 합니다. 번호를 믿는 것과 확인을 생략하는 것은 다른 일입니다.
자주 헷갈리는 용어
| 용어 | 무엇인가 | 시맨틱 버저닝과의 차이 |
|---|---|---|
| 브레이킹 체인지 | 기존 사용자의 코드를 깨뜨리는 변경 | 변경 자체를 가리키는 말이고, 시맨틱 버저닝은 그 변경을 번호로 알리는 규칙입니다. 규칙을 쓰지 않는 코드에도 깨지는 변경은 생깁니다. 다른 점은 쓰는 쪽이 그것을 미리 알 수 있는지뿐입니다 |
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16