글을 작성하게 된 계기
프로젝트의 버전을 자체적인 규칙으로 관리 했는데, 명확한 기준 이 없다 보니 언제 버전을 업데이트할지에 대한 판단이 잘 서지 않았습니다. 이 과정에서 시멘틱 버저닝에 대해 알게 되었고, 이를 정리하기 위해 글을 작성하게 되었습니다.
1. 시멘틱 버저닝
시멘틱 버저닝(Semantic Versioning)은 소프트웨어 버전 관리에서 MAJOR.MINOR.PATCH 형식을 따르는 규칙으로, 버전 번호가 코드 변경의 성격과 호환성에 대한 정보를 전달하도록 설계되었습니다.
MAJOR.MINOR.PATCH 형식은 다음과 같은 의미를 가집니다. 예를 들어, 1.4.2 라는 버전이 있을 때, 1은 MAJOR 버전을, 4는 MINOR 버전을, 2는 PATCH 버전을 의미합니다.
MAJOR: 하위 호환성이 깨지는 변경MINOR: 하위 호환성을 유지하며 기능이 추가된 변경PATCH: 하위 호환성을 유지하며 버그가 수정된 변경
이를 통해 사용자와 개발자가 변경 사항의 의미를 쉽게 이해하고, 의사소통을 간소화할 수 있습니다.
명확한 의사소통: 버전 번호만으로도 변경의 성격을 쉽게 이해할 수 있습니다.안전한 버전관리: MAJOR, MINOR, PATCH를 구분하여 업그레이드 시 발생할 수 있는 위험을 예측할 수 있습니다.표준화된 규칙: 프로젝트 간 일관된 버전 관리로 팀 내 협업이 더욱 수월해집니다.
2. 규칙
시멘틱 버저닝의 규칙에 대해 조금 더 살펴보겠습니다. 이는 다음과 같은 규칙에 따라 버전을 증가시킵니다.
MAJOR 버전 증가: 기존 API를 변경하거나 삭제해 하위 호환성이 깨지는 경우. 새로운 버전을 사용하기 위해 사용자는 기존 코드를 수정해야 합니다. 예: 1.0.0 → 2.0.0MINOR 버전 증가: 기존 API는 유지하면서 새로운 기능을 추가하는 경우. 하위 호환성이 유지되므로 기존 사용자는 영향을 받지 않습니다. 예: 1.0.0 → 1.1.0PATCH 버전 증가: 기존 API를 유지하며 버그를 수정하거나 작은 개선을 적용하는 경우. 수정 사항은 기존 동작에 전혀 영향을 주지 않아야 합니다. 예: 1.0.0 → 1.0.1
또한 시멘틱 버저닝은 MAJOR.MINOR.PATCH 구조에 프리릴리즈(Pre-Release) 와 빌드 메타데이터(Build Metadata)** 를 추가해 버전에 대한 세부 정보를 제공합니다.
2-1. Pre-Release
Pre-Release는 정식 릴리즈 이전 상태 를 나타내며, 소프트웨어가 테스트 또는 개발 중임을 표현합니다. 이는 버전 번호 뒤에 하이픈(-) 과 식별자 를 추가해 나타내며, 예를 들어, 다음과 같습니다.
1.0.0-alpha.1: 첫 번째 알파 버전을 의미하며, 소프트웨어가 아직 초기 개발 단계에 있음을 나타냅니다.1.0.0-beta.2: 두 번째 베타 버전을 나타내며, 알파 버전보다는 안정적이지만 여전히 테스트 중입니다.1.0.0-rc.1: 첫 번째 릴리즈 후보(Release Candidate)로, 정식 릴리즈에 매우 가까운 상태입니다.
Pre-Release 버전은 같은 MAJOR.MINOR.PATCH의 정식 버전보다 우선순위가 낮습니다.
1
1.0.0-alpha < 1.0.0-beta < 1.0.0-rc < 1.0.0
2-2. Build Metadata
Build Metadata는 빌드와 배포 환경에 대한 추가 정보를 제공하는 데 사용됩니다. 이는 기능적 차이는 없지만, 특정 빌드나 배포를 추적하거나 디버깅에 유용합니다. 빌드 메타데이터는 버전 번호 뒤에 플러스(+) 기호 를 붙이고 메타데이터 정보를 추가하여 표시합니다. 예를 들어, 다음과 같습니다.
1.0.0+build.123: 123번째 빌드를 나타냅니다.1.0.0+exp.sha.5114f85: 특정 Git 커밋 정보를 포함하고 있습니다.1.0.0+20231125: 빌드가 생성된 날짜를 메타데이터를 추가해 나타냅니다.
Pre-Release와 Build Metadata를 함께 활용하면 배포 상태와 빌드 정보를 세부적으로 나타낼 수 있습니다.
1.0.0-alpha.1+build.101: 알파 단계에서 빌드 번호를 포함한 버전으로, 초기 개발 단계에서 테스트 목적으로 배포된 빌드를 나타냅니다. 이 버전은 알파 상태(alpha.1)이며, 101번째 빌드임을 표시합니다.1.0.0-rc.1+exp.sha.abcdef1: 첫 번째 릴리즈 후보(rc.1) 버전이며, 특정 Git 커밋(abcdef1)을 기반으로 빌드된 상태를 나타냅니다. 이 버전은 릴리즈 직전에 배포된 빌드의 커밋 출처를 추적하거나, 릴리즈 준비 상태를 확인할 때 유용합니다.1.0.0+build.123: 정식 릴리즈 이후의 상태로, 123번째 빌드를 나타냅니다. 운영 환경에서 배포된 빌드 또는 추가적으로 생성된 빌드를 관리하거나 디버깅 시 활용됩니다.
2-3. 의존성
시멘틱 버저닝은 의존성 관리를 더 체계적으로 만들기 위해 사용됩니다. 개발 환경에서 라이브러리나 패키지의 버전을 관리할 때, 특정 규칙을 이해하고 활용해야 의존성 충돌을 방지할 수 있습니다. 예를 들어, Node.js의 package.json 또는 Python의 requirements.txt에서 시멘틱 버저닝은 의존성 범위를 지정하는 데 사용됩니다. 주로 ^(Caret)와 ~(Tilde) 기호를 통해 버전 범위를 설정합니다.
^(Caret): 같은 MAJOR 버전 내에서만 업데이트를 허용합니다. 예를 들어, ^1.2.0은 1.2.0부터 1.9.x까지 업데이트가 가능하지만, 2.0.0은 허용되지 않습니다. 이는 하위 호환성을 유지하면서 새로운 기능을 수용하고자 할 때 적합한 방식입니다.~(Tilde): 같은 MINOR 버전 내에서만 업데이트를 허용합니다. 예를 들어, ~1.2.0은 1.2.0부터 1.2.x까지 업데이트가 가능하지만, 1.3.0은 포함되지 않습니다. 이 방식은 특정 MINOR 버전에서의 안정성을 우선시하며, 큰 변화 없이 작은 수정 사항만 적용하고자 할 때 유용합니다.고정 버전:: 특정 버전을 명시적으로 지정하는 방식입니다. 예를 들어, 1.2.3으로 설정하면 해당 버전만 설치 가능하며, 다른 버전은 허용되지 않습니다. 이는 중요한 의존성으로 인해 특정 버전이 반드시 필요한 경우, 또는 의존성 충돌을 방지하기 위해 사용됩니다.
3. 한계
시멘틱 버저닝에도 - 의도하지 않은 하위 호환성 문제, 규칙 준수의 어려움, 복잡한 프로젝트에서의 관리 문제, 주관적 판단의 어려움 와 같은 문제점/한계가 존재합니다.
의도하지 않은 하위 호환성 문제: API를 변경할 때, 예상치 못한 방식으로 기존 코드가 동작하지 않거나 깨질 수 있습니다. 예를 들어, 버전 1.2.0에서 내부 동작을 변경했지만, 이 변경이 기존 사용자 코드에 부정적인 영향을 줄 수 있습니다.규칙 준수의 어려움: 시멘틱 버저닝 규칙을 철저히 지키지 않으면 사용자에게 혼란을 줄 수 있습니다. 예를 들어, 실제로 하위 호환성이 깨졌음에도 불구하고 MAJOR 버전이 아닌 MINOR 버전만 증가시켰다면, 사용자는 예상치 못한 코드 수정 부담을 겪게 될 수 있습니다.복잡한 프로젝트에서의 관리 문제: 대규모 프로젝트에서는 모듈 간 의존성을 관리하는 것이 매우 까다로울 수 있습니다. 여러 모듈의 버전을 각각 독립적으로 관리해야 하거나, 의존성 충돌을 해결하기 위해 많은 시간과 노력이 필요할 수 있습니다.주관적 판단의 어려움: 버그 수정과 새로운 기능 추가를 구분하거나, 변경 사항의 영향을 평가하는 과정에서 주관적인 판단이 개입될 수 있습니다. 이로 인해 부적절한 버전 업데이트가 이루어질 가능성이 있으며, 결과적으로 사용자와 팀원에게 혼란을 줄 수 있습니다.
4. 정리
시멘틱 버저닝을 활용하면 어떤 기준으로 버전을 관리할지에 대한 가이드가 서게 되므로, 이를 통해 프로젝트를 체계적으로 관리해 봅시다.