엔지니어링

Keep a Changelog, 실제로 적용해 보니

4분 분량 업데이트

Keep a Changelog는 CHANGELOG.md를 위한 한 페이지짜리 관례다. 최신 버전을 맨 위에, 버전마다 번호와 ISO 날짜를 가진 섹션 하나씩, 여섯 가지 유형(Added, Changed, Deprecated, Removed, Fixed, Security) 아래 묶인 항목들, 그리고 릴리스 사이의 항목들을 위한 맨 위의 Unreleased 섹션. 이것을 인용하는 대부분의 팀은 그중 약 삼분의 이만 구현하며, 그들이 빼먹는 삼분의 일이 바로 사용자를 보호하는 삼분의 일이다.

Olivier Lacan은 2014년에 Keep a Changelog를 발표하면서, 대부분의 소프트웨어 관련 글보다 더 잘 버텨온 한 문장을 남겼다. 친구들이 체인지로그에 git log를 그대로 쏟아붓게 두지 마라. 십 년이 지난 지금, 이것은 소프트웨어의 이 구석에서 표준에 가장 가까운 것이다. 요약이 아니라 원문을 읽을 가치가 있다. 이 글은 빠지는 부분들에 관한 것이다.

Keep a Changelog는 무엇을 요구하는가

저장소 루트에 있는 CHANGELOG.md, 최신순, 버전마다 섹션 하나. 각 버전은 번호와 ISO 날짜를 가지며, 그 항목들을 여섯 가지 유형 아래 묶는다.

유형용도빼먹을 때의 대가
Added새로운 기능없음. 아무도 이것은 빼먹지 않는다
Changed기존 동작의 변경독자가 동작이 바뀐 것을 오류를 통해 알게 된다
Deprecated곧 제거될 기능제거가 예정된 사건이 아니라 사고가 되어버린다
Removed이번 릴리스에서 제거된 기능제거인지 버그인지 아무도 구분할 수 없다
Fixed버그 수정없음. 이것도 아무도 빼먹지 않는다
Security취약점그것을 찾고 있던 그 한 명의 독자가 찾지 못한다

여기에 맨 위의 Unreleased 섹션이 더해진다. 그래서 항목이 병합되는 즉시 넣어둘 곳이 있고, 누구나 다음에 무엇이 올지 볼 수 있다.

이것이 거의 전부다. 나머지는 근거다. 항목은 사람을 위한 것이고, 변경 사항마다 항목 하나이며, 이 파일은 로그가 아니라 문서라는 것.

Keep a Changelog의 어떤 부분이 빠지는가

Unreleased 섹션, 이어서 여섯 유형 중 네 개(Security도 그중 하나)가 순서대로 빠진다.

Unreleased가 가장 먼저 사라진다. 이것은 기한이 없는 섹션이라, 유지 관리가 가장 먼저 멈추는 섹션이며, 사라지고 나면 항목은 릴리스 시점에 커밋 히스토리로부터 쓰이게 된다. 그것이 바로 명세가 서두에서 경고하는 git log 덤프이며, 서서히 그렇게 도달하게 된다. 체인지로그 자동화는 대체로 이 섹션을 누군가 기억하지 않아도 살아 있게 유지하는 것에 관한 글이다.

여섯 유형이 두 개로 무너진다. 실제 체인지로그 대부분은 결국 Added와 Fixed로 귀결된다. Changed와 Deprecated는 누군가 무엇에 의존하고 있었는지에 대한 판단을 요구하기 때문이다. 그 판단이야말로 가치 있는 부분이다. 특히 Deprecated는 미래에 대한 약속인 유일한 유형이며, 그것을 빼먹는 것이 제거가 사고로 변하는 방식이다. 그 약속을 지키는 메커니즘은 API를 비추천 처리하는 방법에 있다.

Security가 더는 분리되지 않는다. Fixed 아래 등록된 보안 수정은 그것을 찾고 있던 바로 그 독자에게 보이지 않는다. 수정이 사소하더라도, 특히 주목받고 싶지 않을 때일수록 분리해서 유지하라.

이 명세는 무엇에 답하지 않는가

이것은 파일 형식이다. 이것을 도입한 직후 바로 마주치게 되는 질문들에 대해서는 아무것도 말하지 않는다.

  • 어떻게 사람들이 그것을 알게 되는가? 저장소 안의 파일은 기여자에게는 닿는다. GitHub를 한 번도 열어본 적 없는 고객에게는 닿지 않는다.
  • 버전이 없는 제품은 어떻게 하는가? 지속적으로 배포되는 서비스에는 묶을 수 있는 v4.2.0이 없다. 대부분의 팀은 날짜로 대체하며, 이것은 잘 작동하고, 명세는 이를 승인하지도 금지하지도 않는다.
  • 누가 항목을 쓰는가? 명세는 사람이 쓴다고 가정한다. 언제 쓰는지는 말하지 않는다.
  • 여러 독자층은 어떻게 하는가? 파일 하나는 개발자에게 유용하다. 그것은 비기술적인 관리자에게 같은 내용을 제공하지 않으며, 그들을 위해 손으로 다시 포맷하는 것이 중복이 시작되는 지점이다. 체인지로그 대 릴리스 노트가 이 명세가 남겨둔 분리 작업이다.

이 발상의 더 엄격한 파생인 Common Changelog는 이 중 일부를 조인다. 특정 항목 문구를 금지하고, 변경 사항으로의 링크를 요구하며, 독자가 누구인지에 대해 확고한 입장을 가진다. Keep a Changelog의 느슨한 부분들이 팀에서 계속 논쟁거리라면 읽어볼 가치가 있다.

git log를 쏟아붓지 않고 Keep a Changelog를 자동화할 수 있는가

가능하다. 구조화된 커밋으로부터 초안을 도출하고, 유형을 미리 채운 상태로 Unreleased에 넣고, 릴리스가 잘리기 전에 사람이 문구를 편집하도록 요구하라. 명세의 경고는 도구가 아니라 결과물에 관한 것이다. 커밋으로부터 초안을 도출하는 것은 괜찮다. 그 초안을 편집 없이 그대로 발행하는 것이 명세가 반대하는 대상이다.

기계는 수집과 포맷팅을 담당한다. 그것은 기계가 잘하는 일이다. 사람은 선별과 문구를 담당한다. 그것은 기계가 잘하지 못하는 일이다. Conventional commits는 이것이 의존하는 두 계층 분리와, 어떤 커밋 유형이 위 여섯 범주 중 어디에 대응하는지를 다룬다. 우리의 체인지로그 도구 정리는 수집 부분을 위해 무엇이 있는지 다룬다.

Keep a Changelog는 어디서 충분하지 않게 되는가

배포에서 멈춘다. Keep a Changelog는 “이 파일이 어떤 모습이어야 하는가”에 대한 좋은 답이다. “우리 사용자들이 무엇이 바뀌었는지 어떻게 알게 되는가”에 대한 답은 아니다. 저장소 안의 Markdown 파일은 여러분의 사용자가 기여자일 때만 작동하는 배포 전략이기 때문이다.

그것이 대부분의 팀이 두 번째로 마주치는 간극이다. 파일 자체는 괜찮은데, 팀 밖의 아무도 그것을 읽지 않는다. 이것을 해결한다는 것은 항목들이 다른 어딘가에서 렌더링될 수 있는 데이터가 되어야 한다는 뜻이며, 이것은 파일을 포맷하는 것과는 다른 문제다. 그것이 체인지로그 예시가 저장소 파일이 아니라 공개된 체인지로그 페이지들을 모아 놓은 이유다. 그 항목들을 사람들이 다시 찾아오는 것으로 바꾸는 방법은 체인지로그 페이지 만드는 법에서 다룬다.

그럼에도 이 명세를 도입하라. 반나절이면 되고, 두 번째 문제를 다룰 수 있게 만들어주며, 여전히 이 주제에 관해 쓰인 최고의 한 페이지다.

FAQ

Keep a Changelog는 표준인가? 널리 채택된 관례이지, 표준화 기구의 사양이 아니다. 도구들(릴리스 스크립트, 린터, 파서)이 그 형태를 충분히 자주 가정하기 때문에, 이를 따르는 것이 호환성을 사준다.

Unreleased 섹션에는 무엇이 들어가는가? 병합되었지만 번호가 매겨진 릴리스로는 아직 출시되지 않은 변경 사항마다의 항목. 릴리스가 잘리면 그 섹션은 버전과 날짜로 이름이 바뀌고, 그 위에 새로운 빈 Unreleased 섹션이 놓인다.

체인지로그는 시맨틱 버저닝을 사용해야 하는가? Keep a Changelog는 이를 권장하지만 요구하지는 않는다. 라이브러리와 API는 이로부터 이득을 얻는다. 지속적으로 배포되는 서비스는 보통 날짜로 대체하며, 이 형식은 그것을 수용한다.

보안 수정 사항은 공개되기 전에 체인지로그에 있어야 하는가? 수정이 출시될 때 항목을 추가하되, 운영자가 조치를 취할 수 있을 만큼의 세부 사항만 담아라. 공동 공개 날짜까지 항목을 미루는 것은 정상이지만, 아예 빠뜨리는 것은 그렇지 않다.


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

changeloop 관련 페이지: changelog 예시, changelog 도구 비교

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