
개요[편집 / 원본 편집]
유의적 버전 또는 시맨틱 버전(영어: Semantic Versioning, SemVer)은 소프트웨어의 버전 번호에 일정한 의미를 부여하여, 배포판 사이의 변경 범위와 하위 호환성 여부를 표현하는 버전 표기 규칙이다.[1]
기본 형식은 MAJOR.MINOR.PATCH이며, 한국어 공식 문서에서는 이를 각각 주 버전, 부 버전, 수 버전으로 번역한다.[1] 예를 들어 2.4.1이라는 버전은 주 버전이 2, 부 버전이 4, 수 버전이 1이라는 뜻이다.
유의적 버전의 목적은 단순히 버전을 보기 좋게 표시하는 것이 아니라, 버전 번호만으로도 어느 정도의 API 변경이 있었는지 알 수 있게 하는 데 있다. 일반적으로 주 버전이 바뀌면 기존 코드와 호환되지 않는 변경이 있었을 가능성이 높고, 부 버전이 바뀌면 기존 코드와 호환되는 기능 추가가 있었음을 뜻하며, 수 버전이 바뀌면 기존 코드와 호환되는 버그 수정이 있었음을 뜻한다.
다만 유의적 버전이 의미를 가지려면 해당 소프트웨어가 먼저 명확한 공개 API를 선언해야 한다.[2] 여기서 공개 API는 외부 사용자가 의존할 수 있는 함수, 클래스, 명령어, 설정 형식, 데이터 형식, 프로토콜, 문서화된 동작 등을 포함할 수 있다. 공개 API가 명확하지 않으면 어떤 변경이 호환성을 깨뜨리는 변경인지 판단하기 어렵다.
구성[편집 / 원본 편집]

유의적 버전은 기본적으로 주 버전, 부 버전, 수 버전의 세 부분으로 구성된다. 여기에 필요에 따라 선행 배포 버전과 빌드 메타데이터를 덧붙일 수 있다.
| 구성 요소 | 형식상의 위치 | 의미 | 증가 또는 사용 조건 |
|---|---|---|---|
| 주 버전 | MAJOR | 기존 공개 API와 호환되지 않는 변경 | 하위 호환성을 깨뜨리는 변경이 공개 API에 포함될 때 증가 |
| 부 버전 | MINOR | 기존 공개 API와 호환되는 기능 추가 | 하위 호환성을 유지하면서 기능을 추가하거나 공개 API 일부를 폐기 예정으로 표시할 때 증가 |
| 수 버전 | PATCH | 기존 공개 API와 호환되는 버그 수정 | 잘못된 동작을 고치되 공개 API 호환성을 유지할 때 증가 |
| 선행 배포 버전 | -alpha, -beta.1, -rc.1 등 | 정식 배포 전 버전 | 아직 안정판이 아니거나 호환성 요구사항이 완전히 보장되지 않을 수 있음을 나타낼 때 사용 |
| 빌드 메타데이터 | +build.1, +exp.sha 등 | 빌드 식별 정보 | 빌드 번호, 커밋 해시, 빌드 날짜 등 버전 우선순위에 영향을 주지 않는 정보를 표시할 때 사용 |
형식[편집 / 원본 편집]
유의적 버전의 일반적인 형식은 다음과 같다.
MAJOR.MINOR.PATCH
MAJOR.MINOR.PATCH-PRERELEASE
MAJOR.MINOR.PATCH+BUILD
MAJOR.MINOR.PATCH-PRERELEASE+BUILD예시는 다음과 같다.
| 버전 | 설명 |
|---|---|
| 1.0.0 | 가장 기본적인 정식 버전 형식 |
| 1.2.3 | 주 버전 1, 부 버전 2, 수 버전 3 |
| 2.0.0 | 주 버전이 증가한 버전으로, 기존 공개 API와 호환되지 않는 변경이 포함되었을 수 있음 |
| 1.4.0 | 부 버전이 증가한 버전으로, 기존 공개 API와 호환되는 기능 추가가 있었음을 뜻함 |
| 1.4.1 | 수 버전이 증가한 버전으로, 기존 공개 API와 호환되는 버그 수정이 있었음을 뜻함 |
| 2.3.7-beta.3 | 2.3.7 정식 배포 이전의 세 번째 베타 계열 선행 배포 버전 |
| 1.0.0+20130313144700 | 빌드 메타데이터가 포함된 버전 |
| 1.0.0-alpha+001 | 선행 배포 버전과 빌드 메타데이터가 모두 포함된 버전 |
버전 증가 규칙[편집 / 원본 편집]
주 버전[편집 / 원본 편집]
주 버전(영어: major version)은 기존 공개 API와 호환되지 않는 변경이 발생했을 때 증가한다. 예를 들어 함수 이름이 바뀌거나, 기존 매개변수의 의미가 달라지거나, 기존에 동작하던 사용 방식이 더 이상 지원되지 않는다면 주 버전을 올리는 것이 원칙이다.
주 버전이 증가하면 부 버전과 수 버전은 0으로 초기화한다. 예를 들어 1.8.5에서 호환되지 않는 변경이 발생했다면 다음 버전은 일반적으로 2.0.0이 된다.
파이썬의 파이썬 2와 파이썬 3의 관계는 주 버전 변화가 호환성에 큰 영향을 줄 수 있음을 보여 주는 대표적인 사례로 자주 언급된다. 파이썬 2에서 작성된 코드가 파이썬 3에서 그대로 동작하지 않는 경우가 많았기 때문에, 사용자는 주 버전 변화에 맞추어 코드를 수정해야 했다.
부 버전[편집 / 원본 편집]
부 버전(영어: minor version)은 기존 공개 API와 하위 호환성을 유지하면서 새로운 기능을 추가할 때 증가한다. 또한 공개 API의 일부를 앞으로 제거할 예정으로 표시하는 경우에도 부 버전을 올리는 것이 원칙이다.[1]
부 버전이 증가하면 수 버전은 0으로 초기화한다. 예를 들어 1.4.3에서 하위 호환성을 유지하는 기능이 추가되었다면 다음 버전은 일반적으로 1.5.0이 된다.
부 버전 증가가 반드시 아무 위험도 없다는 뜻은 아니다. 새 기능이 기존 코드와 호환되도록 설계되었더라도, 실제 사용 환경에서는 의존성, 설정, 보안 정책, 폐기 예정 기능 등의 영향으로 추가 확인이 필요할 수 있다.
수 버전[편집 / 원본 편집]
수 버전(영어: patch version)은 기존 공개 API와 하위 호환성을 유지하면서 버그를 수정할 때 증가한다. 예를 들어 1.5.0에서 내부 오류를 수정했지만 공개 API의 사용 방식은 그대로 유지된다면 다음 버전은 일반적으로 1.5.1이 된다.
수 버전만 증가한 경우에는 보통 기존 코드를 수정할 필요가 없다. 다만 기존 코드가 버그에 의존하고 있었거나, 수정된 동작이 실제 운영 환경의 결과에 영향을 주는 경우에는 예외적으로 코드나 설정을 조정해야 할 수 있다.
초기 개발 버전과 1.0.0[편집 / 원본 편집]
주 버전이 0인 0.y.z 형식은 초기 개발 단계를 나타낸다. 이 단계에서는 공개 API가 안정적이라고 간주되지 않으며, 언제든 호환되지 않는 변경이 발생할 수 있다.[1]
1.0.0은 공개 API가 정의된 첫 안정판으로 볼 수 있다. 이후 버전 번호는 1.0.0에서 정의한 공개 API가 어떻게 바뀌는지에 따라 증가한다.
| 버전 범위 | 일반적인 의미 |
|---|---|
| 0.y.z | 초기 개발 단계. 공개 API가 안정적이라고 보기 어려움 |
| 1.0.0 | 공개 API가 정의된 첫 안정판 |
| 1.x.y 이상 | 정의된 공개 API를 기준으로 호환성 규칙을 적용하는 단계 |
선행 배포 버전[편집 / 원본 편집]
선행 배포 버전(영어: pre-release version)은 정식 배포 이전의 알파, 베타, 릴리스 후보 등을 표시할 때 사용한다. 수 버전 뒤에 붙임표(-)를 붙이고, 마침표(.)로 구분된 식별자를 덧붙인다.
예시는 다음과 같다.
| 선행 배포 버전 | 일반적인 의미 |
|---|---|
| 1.0.0-alpha | 초기 시험용 알파 버전 |
| 1.0.0-alpha.1 | 첫 번째 알파 계열 세부 버전 |
| 1.0.0-beta | 베타 버전 |
| 1.0.0-beta.2 | 두 번째 베타 계열 세부 버전 |
| 1.0.0-rc.1 | 첫 번째 릴리스 후보 버전 |
선행 배포 버전은 같은 주·부·수 버전의 정식 버전보다 우선순위가 낮다. 예를 들어 2.3.7-beta.3은 2.3.7보다 낮은 버전으로 취급된다.
빌드 메타데이터[편집 / 원본 편집]
빌드 메타데이터(영어: build metadata)는 더하기(+) 기호 뒤에 덧붙이는 부가 정보이다. 빌드 번호, 빌드 날짜, 커밋 해시, 빌드 환경 등을 표시하는 데 사용할 수 있다.
예시는 다음과 같다.
| 버전 | 설명 |
|---|---|
| 1.0.0+001 | 빌드 번호가 포함된 버전 |
| 1.0.0+20130313144700 | 빌드 시각 또는 날짜 형식의 메타데이터가 포함된 버전 |
| 1.0.0-beta+exp.sha.5114f85 | 선행 배포 버전과 빌드 메타데이터가 함께 포함된 버전 |
빌드 메타데이터는 버전 우선순위 비교에서 무시된다. 따라서 주·부·수 버전과 선행 배포 버전이 같고 빌드 메타데이터만 다른 경우, 두 버전의 우선순위는 같다.
버전 우선순위[편집 / 원본 편집]
유의적 버전에서는 버전의 우선순위를 비교할 때 주 버전, 부 버전, 수 버전, 선행 배포 버전 순서로 비교한다. 빌드 메타데이터는 우선순위 비교에 영향을 주지 않는다.
| 비교 예시 | 결과 | 이유 |
|---|---|---|
| 1.0.0 < 2.0.0 | 참 | 주 버전 2가 주 버전 1보다 크기 때문 |
| 2.0.0 < 2.1.0 | 참 | 부 버전 1이 부 버전 0보다 크기 때문 |
| 2.1.0 < 2.1.1 | 참 | 수 버전 1이 수 버전 0보다 크기 때문 |
| 1.0.0-alpha < 1.0.0 | 참 | 선행 배포 버전은 같은 버전의 정식 버전보다 낮기 때문 |
| 1.0.0-alpha < 1.0.0-alpha.1 | 참 | 앞선 식별자가 같을 때 더 많은 선행 배포 식별자를 가진 쪽이 더 높게 비교될 수 있기 때문 |
| 1.0.0+001 = 1.0.0+20130313144700 | 우선순위상 같음 | 빌드 메타데이터는 우선순위 비교에서 무시되기 때문 |
공식 명세에서 제시하는 선행 배포 버전의 우선순위 예시는 다음과 같다.[2]
1.0.0-alpha
< 1.0.0-alpha.1
< 1.0.0-alpha.beta
< 1.0.0-beta
< 1.0.0-beta.2
< 1.0.0-beta.11
< 1.0.0-rc.1
< 1.0.0장점[편집 / 원본 편집]
유의적 버전의 장점은 다음과 같다.
한계와 주의점[편집 / 원본 편집]
유의적 버전은 모든 문제를 자동으로 해결하는 규칙은 아니다. 다음과 같은 점에 주의해야 한다.
- 공개 API가 명확하게 정의되어 있지 않으면 버전 번호의 의미가 약해진다.
- 개발자가 규칙을 잘못 적용하면 버전 번호와 실제 변경 내용이 일치하지 않을 수 있다.
- 응용 프로그램의 사용자 인터페이스 변경, 데이터 파일 형식 변경, 운영 환경 변경 등은 API 변경과 다르게 판단될 수 있다.
- 보안 문제나 긴급 패치의 경우, 기존 정책과 별도의 배포 판단이 필요할 수 있다.
- 생태계마다 버전 범위 해석 방식이 다를 수 있으므로, 실제 의존성 지정 방식은 사용하는 패키지 관리자 문서를 함께 확인해야 한다.
예시[편집 / 원본 편집]
하위 호환되는 버그 수정[편집 / 원본 편집]
기존 버전이 1.2.3이고, 공개 API는 그대로 유지하면서 내부 버그만 수정했다면 다음 버전은 일반적으로 다음과 같이 증가한다.
1.2.3 -> 1.2.4하위 호환되는 기능 추가[편집 / 원본 편집]
기존 버전이 1.2.3이고, 기존 API와 호환되는 새 기능을 추가했다면 다음 버전은 일반적으로 다음과 같이 증가한다.
1.2.3 -> 1.3.0하위 호환되지 않는 변경[편집 / 원본 편집]
기존 버전이 1.2.3이고, 공개 API의 사용 방식이 바뀌어 기존 코드가 수정 없이 동작하지 않을 수 있다면 다음 버전은 일반적으로 다음과 같이 증가한다.
1.2.3 -> 2.0.0정식 배포 전 버전[편집 / 원본 편집]
2.0.0 정식 배포 전 테스트 버전을 배포하려면 다음과 같은 형식을 사용할 수 있다.
2.0.0-alpha
2.0.0-beta.1
2.0.0-rc.1같이 보기[편집 / 원본 편집]
외부 링크[편집 / 원본 편집]
각주[편집 / 원본 편집]
- ↑ 1.0 1.1 1.2 1.3 유의적 버전 2.0.0, Semantic Versioning 공식 한국어 문서.
- ↑ 2.0 2.1 Semantic Versioning 2.0.0, Semantic Versioning 공식 문서.