엔지니어링

시맨틱 버저닝과 당신의 체인지로그, 함께 보기

4분 분량

시맨틱 버저닝은 호출자가 체인지로그 항목을 하나도 읽기 전에 릴리스가 얼마나 아플 수 있는지 알려준다. 2.4.1에서 2.5.0으로 가는 것은 이렇게 말한다. 새로운 기능, 아무것도 깨지지 않는다. 2.5.0에서 3.0.0으로 가는 것은 이렇게 말한다. 업데이트 전에 이 항목을 읽어라. 체인지로그와 버전 번호는 두 형식으로 같은 것을 주장해야 하며, 둘 사이의 마찰 대부분은 정확히 둘이 일치하지 않을 때 나타나는데, 이는 명세가 시사하는 것보다 더 자주 일어난다.

버전의 각 숫자는 실제로 무엇을 약속하는가

시맨틱 버저닝은 세 숫자를 정의한다. MAJOR.MINOR.PATCH, 각각 무엇이 그것을 트리거하는지에 대한 엄격한 규칙이 있다. MAJOR 상승은 호환되지 않는 변경을 의미한다. 올바르게 작성된 기존 통합이 알아챌 수 있고 그 때문에 바뀌어야 하는 무언가다. MINOR 상승은 새롭고 하위 호환되는 기능을 의미한다. 기존의 어떤 것도 깨지지 않고, 새로운 것이 사용 가능해진다. PATCH 상승은 하위 호환되는 수정을 의미한다. 동작이 문서화된 것에 더 가까워지고, 의도적으로 이전 동작에 의존한 사람이라면 아무것도 알아채지 못해야 한다.

상승의미항목은 이렇게 읽혀야 한다
MAJOR (1.x.x -> 2.0.0)호환되지 않는 변경“업데이트 전에 조치가 필요하다”
MINOR (1.2.x -> 1.3.0)새롭고 호환되는 기능“지금부터 사용 가능, 다른 건 안 바뀜”
PATCH (1.2.3 -> 1.2.4)호환되는 수정“이제 문서화된 대로 동작한다”

이 표는 거꾸로도 테스트가 된다. 항목이 자기 행처럼 읽히지 않는다면, 버전 번호가 틀렸거나 항목이 실제로 일어난 일을 과소평가하거나 과대평가하는 것이다.

버전 관리 목적으로 무엇이 호환되지 않는 것으로 간주되는가

무언가가 API 체인지로그에 속하는지를 결정하는 것과 같은 테스트다. 이전 동작에 맞춰 작성되고 그 이후 손대지 않은 올바른 호출자가 이 변경 때문에 다르게 동작할 수 있는가. 호환되지 않는 변경이란 무엇이고 어떻게 출시하는가가 그 판단을 완전히 다루며, 호환되지 않아 보이지만 아닌 경우와 작아 보이지만 아닌 경우도 포함한다. 버전 관리 목적으로 짧게 말하면, 답이 그렇다면, 변경이 내부적으로 실제로 얼마나 많은 코드를 건드렸는지와 상관없이 상승은 MAJOR다. 버전 번호는 팀의 노력이 아니라 호출자에게 미치는 결과를 추적한다.

체인지로그 항목은 버전 상승과 어떻게 맞아야 하는가

하나의 항목, 하나의 상승 카테고리를, 맨 앞에서 밝힌다. 표의 패턴이 그대로 이어진다. 호환되지 않는 항목은 그것을 도입한 버전 아래에 놓이며, 먼저 경고로, 그다음 설명으로 표현된다. 추가적인 항목은 자신의 MINOR 버전 아래에 놓이며, 사용 가능성으로 표현된다. 수정은 자신의 PATCH 버전 아래에 놓이며, 정정으로 표현된다. 하나의 항목에서 카테고리를 섞는 것, 예를 들어 호환되지 않는 변경을 무관한 수정과 같은 단락에 접어 넣는 것은 독자가 정말로 중요했던 그 한 가지를 놓치게 만드는 방식이다.

## 3.0.0 (2026-09-07)

### Changed
- **BREAKING:** `GET /reports`가 이제 금액을 소수점 대신 최소 통화 단
  위(센트)의 정수로 반환한다. `amount`를 직접 읽는 코드를 업데이트하라
  .

## 2.9.0 (2026-09-01)

### Added
- 보고서를 이제 `status`로 필터링할 수 있다.

## 2.8.4 (2026-08-28)

### Fixed
- `GET /reports?status=`가 알 수 없는 상태에 대해 400 대신 빈 페이지를
   반환했다.

위에서 아래로 읽으면 버전 번호와 섹션 라벨이 같은 것을 두 번 말한다. 바로 그것이 목적이다. 제목만 훑어보는 독자도 한 줄도 열지 않고 올바른 위험 판단을 얻는다.

파괴적 변경 규칙은 1.0.0 이전에도 똑같이 적용되는가

아니다, 그리고 “그게 정말 파괴적이었나”를 둘러싼 대부분의 혼란이 여기서 나온다. SemVer는 메이저 버전 0, 즉 0.y.z가 초기 개발용이라고 명시한다. 언제든 무엇이든 바뀔 수 있고, 공개 API는 안정적이라고 여겨져서는 안 된다. 0.4.0에서 0.5.0으로의 상승은 스펙을 어기지 않고도 파괴적 변경을 담을 수 있다. 메이저 버전 보장은 프로젝트가 1.0.0을 출시한 이후에야 시작되기 때문이다. 체인지로그 항목은 무엇이 깨졌는지에 대해 여전히 독자에게 같은 정직함을 빚지고 있다. 달라지는 것은 오직, 1.0.0에 이르기 전까지는 버전 번호 자체가 믿을 만한 신호가 아니라는 점뿐이다.

제품이 개별 버전을 출시하지 않는다면 어떤가

대부분의 SaaS 제품은 지속적으로 배포되며 호출자에게 버전 번호를 절대 보여주지 않는데, 이것이 이 원칙의 필요성을 없애지는 않고, 그것을 보통 담아냈을 숫자만 없앤다. 체인지로그 항목이 모든 일을 혼자 해야 한다. 변경이 호환되지 않는지, 추가적인지, 수정인지를, 시맨틱 버저닝이 쓰는 것과 같은 세 단어로, 그것을 붙일 버전 필드가 없어도 명확히 말해야 한다. 일부 팀은 체인지로그 항목을 링크할 수 있는 무언가에 고정하기 위해서만, 호출자에게 직접 보여주지 않고 순전히 내부용 버전을 유지한다.

이것이 API 체인지로그에는 구체적으로 어떻게 적용되는가

거의 다른 어디보다 더 엄격하게, API의 호출자는 예상치 못한 변경에 어깨를 으쓱할 수 있는 사람이 아니라 코드이기 때문이다. API 체인지로그: 무엇을 공개하고 누가 읽는가가 그 문서의 완전한 형태를 다룬다. 여기서의 버전 관리 원칙은 그것의 breaking 섹션과 additive 섹션을 정직하게 유지하는 것이다. 마이그레이션 기간 동안 v1과 v2를 나란히 제공하는 것처럼 여러 버전을 동시에 제공하는 API는 사실상 하나의 패키지가 아니라 전체 인터페이스 규모에서 시맨틱 버저닝을 적용하고 있는 것이며, 같은 세 단어 어휘가 여전히 모든 항목에 적용된다.

Keep a Changelog는 버전 관리에 대해 무엇을 말하는가

이름으로 시맨틱 버저닝과 직접 연결되며, 이 글이 쓰는 것과 같은 카테고리 어휘를 권장한다. Added, Changed, Deprecated, Removed, Fixed, Security. Keep a Changelog, 실전편이 그 명세를 채택하는 방법을, 팀이 거기서 벗어나는 지점까지 포함해서 다룬다. 이 겹침은 우연이 아니다. 두 명세 모두 반대편 끝에서 같은 문제를 풀려고 하는 것이다. 하나는 버전 번호를 표준화하고 다른 하나는 그것을 설명하는 항목을 표준화한다.

FAQ

모든 체인지로그 항목에 버전 번호가 필요한가? 제품이 버전을 출시한다면 그렇다. 숫자가 독자로 하여금 항목을 먼저 읽지 않고도 “이것이 나에게 얼마나 영향을 미치는가”로 바로 넘어갈 수 있게 해주기 때문이다. 제품이 버전 필드 없이 지속적으로 배포된다면, 항목의 표현이 그 신호를 혼자 담아야 한다.

MAJOR 상승과 호환되지 않는 변경 항목의 차이는 무엇인가? 둘은 같은 사건을 두 방식으로 설명해야 한다. 버전 번호는 기계가 읽는 신호이고(호출자의 도구가 그것에 반응할 수 있다), 체인지로그 항목은 구체적으로 무엇이 바뀌었는지에 대한 사람이 읽는 설명이다.

PATCH 릴리스가 호환되지 않을 수 있는가? 정의상 그러면 안 된다. 그래도 출시되었다면, 발행된 버전을 수정하거나 태그를 다시 붙이지 마라. SemVer FAQ는 호환성을 복원하는 새 버전을 릴리스하거나, 호환되지 않는 변경을 유지한다면 새 MAJOR를 릴리스하고, 문제가 된 버전을 문서화해 사용자가 그것을 건너뛸 수 있게 하라고 말한다.

순전히 내부적인 변경에도 버전 상승이 필요한가? 아니다. 시맨틱 버저닝은 공개 인터페이스를 추적한다. 호출자에게 관찰 가능한 영향이 없는 리팩터링은 내부적으로 상당한 엔지니어링 작업이었더라도 상승도 체인지로그 항목도 필요 없다.


이 글의 기술적 내용은 독립적으로 검토되지 않았습니다. 잘못된 부분이 있으면 알려 주세요. 바로잡겠습니다.

changeloop 관련 페이지: changelog 생성기, 개발자 문서

changeloop
루프를 닫는 changelog를 만드는 팀입니다. 사용자가 무언가를 요청하면 팀이 전달하고, 요청한 사람은 알게 됩니다.