기타 (Other)

시맨틱 버저닝(Semantic Versioning) 정리

Wibaek 2022. 9. 18. 12:36
728x90

npm을 사용하거나 패키지들을 관리할 때 2.9.9, 0.4.1 이런 식의 세 부분으로 나뉜 버전을 보신 적이 있을 겁니다. 사실 이런 버전들은 임의로 정해진 것이 아니라, 규칙에 따라 정해진 것입니다. 이 규칙을 시맨틱 버저닝(Semantic Versioning)이라 합니다.

시맨틱 버저닝의 구성

시맨틱 버저닝은 Major, Minor, Patch의 3 부분으로 나뉘어 있습니다.


Major.Minor.Patch


각각의 버전이 올라가는 기준은 다음과 같습니다.

  • Major version: 하위 버전과 호환되지 않는 API 변경 시
  • Minor version: 하위 호환이 가능한 기능 추가
  • Patch version: 하위 호환이 가능한 버그 수정

그리고 다음과 같은 규칙이 있습니다.

  1. Major version이 올라가면 Minor version과 Patch version은 0부터 다시 시작하며, Minor version이 올라가면 Patch version은 0부터 다시 시작합니다.
  2. 버전이 공개되면 이 이후에는 수정되어서는 안 되고, 수정될 시 새로운 버전으로 공개해야 합니다.
  3. Major version이 0인 경우는 초기 개발을 위한 것이고, 이 버전대는 안정적이지 않음을 유의해야 합니다.
  4. 선행 배포 버전은 버전 다음에 - 를 적고 숫자와 영문자로 식별자를 작성합니다. 이때 선행 배포 버전은 일반 버전보다 낮은 우선순위를 갖습니다. ex) 1.1.0-0.3.3, 1.1.0-alpha < 1.1.0
  5. 또한 선행 배포 버전을 사용하려면 해당 선행 버전의 (Major.Minor.Patch) 정의와 일치하는 버전이 있어야 합니다. 예를 들어 >1.2.3-alpha.3는 1.2.3-alpha.4는 허용시키지만, 3.5.7-alpha.7은 허용시키지 않습니다. 왜냐하면 확실히 3.5.7-alpha.7은 기술적으로는 1.2.3-alpha.3보다 크지만, 1.2.3이 포함되어 있지 않기 때문입니다. 이러한 규칙이 있는 이유는, prerelease는 너무 자주 업데이트되고 불안정하기 때문에 이 사항을 인지해야 하고 , prerelease를 사용하고 싶은 사용자들은 범위에 prerelease 태그를 넣어 선행 배포 버전을 사용하겠다고 명시해야만 사용할 수 있는데, 이를 다음 버전의 선행 배포 버전의 위험도 감수하겠다고 보는 것은 부적절하기 때문입니다.
  6. 개발 버전은 버전 다음에 + 를 적고 숫자와 영문자로 식별자를 작성합니다. 이때 개발 버전은 일반 버전보다 높은 우선순위를 갖습니다. ex) 2.1.0+20220822, 2.1.0+001 > 2.1.0

버전 비교 규칙은 다음이 있습니다.

  1. 숫자로만 이루어진 버전은 숫자 크기로 비교하면 됩니다
  2. 문자로 이루어진 버전은 ASCII 순서대로 비교하면 됩니다
  3. 숫자는 항상 문자보다 낮은 순서를 가집니다

ex) 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

rc란 Release Candidate로 배포 후보를 의미합니다

Version range

npm의 package.json이나 Python poetry의 pyproject.toml등에서 버전을 적을 때 보면 ~(틸트)나 ^(캐럿)을 통하여 버전 범위를 나타내는 것을 볼 수 있습니다. 아래에 이런 방식으로 버전 범위를 나타내는 방법을 소개합니다.

Hyphen Ranges

X.Y.Z - A.B.C

-(하이픈)은 X.Y.Z 이상, A.B.C 이하를 의미합니다. 이때, 시작 버전에 하위 버전을 기재하지 않으면 0으로 보고, 끝 버전에 하위 버전을 기재하지 않으면 무한대로 보면 됩니다. 이는 아래 후술 할 X-Ranges의 규칙을 적용한 것입니다.

  • 1.2.3 - 2.3.4 := >=1.2.3 <=2.3.4
  • 1.2 - 2.3.4 := >=1.2.0 <=2.3.4
  • 1.2.3 - 2.3 := >=1.2.3 <2.4.0
  • 1.2.3 - 2 := >=1.2.3 <3.0.0

X-Ranges

1.2.x | 1.X | 1.2.* | *

X-Ranges에서 x, X, *는 동일한 것으로 아무것이나 사용해도 됩니다. *는 아무 숫자나 들어가도 되다고 생각하면 되는데, 버전을 일부 생략하거나 생략하더라도 *인 것으로 간주합니다. 위의 Hyphen Ranges에서 부분적인 버전을 기재하지 않으면 무한대로 보는 것도 X-Ranges의 원리에 따름입니다.

  • "" (빈 문자열) := * := >=0.0.0
  • 1 := 1.x := 1.x.x := >=1.0.0 <2.0.0
  • 1.2 := 1.2.x := >=1.2.0 <1.3.0

Tilde Ranges

~1.2.3 | ~1.2 | ~1

~(틸드)는 Minor 버전이 정의되어 있으면, Patch 상위 버전을 허용합니다. Minor버전이 정의되어 있지 않으면, Minor 상위 버전까지 허용합니다. 즉 ~A.B.C := >=A.B.C <A.B.X이고, ~A.B := A.B.X이고, ~A := A.X이다

  • ~1.2.3 := >=1.2.3 <1.(2+1). 0 := >=1.2.3 <1.3.0
  • ~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0
  • ~1 := >=1.0.0 <(1+1). 0.0 := >=1.0.0 <2.0.0
  • ~1.2.3-beta.2 := >=1.2.3-beta.2 <1.3.0 (단, 1.2.3-beta.3 등 해당 버전에서의 prerelease는 허용되지만 1.2.4-beta.2 같이 다른 버전의 prerelease는 허용되지 않는다)

Caret Ranges

^1.2.3 | ^0.2.5 | ^0.0.4

^(캐럿)은 가장 왼쪽의 0이 아닌 숫자를 수정하지 않는 선에서 상위 버전을 허용합니다. 즉 Major 버전이 0이 아닐 때는, Minor 버전과 Patch 버전은 자유롭게 올릴 수 있으며, Major 버전이 0일 때는 Minor 버전이 0이 아니면 Patch 버전을 자유롭게 올릴 수 있고, Minor 버전도 0이라면 상위 버전을 허용하지 않습니다.
캐럿은 이런 특징으로 인해 시멘틱 버저닝의 특성을 잘 살렸다고 볼 수 있는데, 왜냐하면 하위 호환을 보장받기에 유용하기 때문입니다. Major 버전이 1 이상인 일반적인 상황에서는 Minor 버전을 올려도 하위 호환이 잘 보장될 것이라 생각할 수 있고, Major 버전이 0 이하인 개발 상황에서는 Minor이나 Patch 버전이 올라가는 것 만으로 하위 호환이 보장되지 않을 수 있는데 캐럿을 사용한다면 이런 상황에서도 하위 호환을 보장받을 가능성이 높기 때문입니다.

  • ^1.2.3 := >=1.2.3 <2.0.0
  • ^0.2.3 := >=0.2.3 <0.3.0
  • ^0.0.3 := >=0.0.3 <0.0.4
  • ^1.2.3-beta.2 := >=1.2.3-beta.2 <2.0.0 (단, 1.2.3-beta.3 등 해당 버전에서의 prerelease는 허용되지만 1.2.4-beta.2 같이 다른 버전의 prerelease는 허용되지 않는다)
  • ^0.0.3-beta := >=0.0.3-beta <0.0.4

또한 캐럿은 Patch 버전이 정의되어 있지 않거나 *일 때, *로 처리하는 것이 아닌 0으로 처리하고, Major 그리고 Minor 버전이 둘 다 0이라도 유연성을 가져 모든 Patch 버전의 변경을 허용한다.

  • ^1.2.* := >=1.2.0 <2.0.0
  • ^0.0.* := >=0.0.0 <0.1.0
  • ^0.0 := >=0.0.0 <0.1.0

또한 캐럿은 Patch 그리고 Minor 버전이 정의되어 있지 않거나 *일 때, *로 처리하는 것이 아닌 0으로 처리하고, Major 버전이 0이라도 유연성을 가져 모든 Major 버전의 변경을 허용한다.

  • ^1.* := >=1.0.0 <2.0.0
  • ^0.* := >=0.0.0 <1.0.0

레퍼런스

https://semver.org/

Semantic Versioning 2.0.0

Semantic Versioning spec and website

semver.org

https://docs.npmjs.com/cli/v6/using-npm/semver

semver | npm Docs

The semantic versioner for npm

docs.npmjs.com

728x90