エンジニアリング

CHANGELOG.mdに何を書き、どう最新に保つか

1分で読めます

CHANGELOG.mdはリポジトリのルートに置くMarkdownファイルで、リリースされたバージョンごとに、プロジェクトのユーザーが行動に移せる言葉で何が変わったかを列挙する。このファイルを読むのは、アップグレードするかを決める人、アップグレード後にデバッグする人、そしてプロジェクトのページにこれを表示するパッケージレジストリやリリースツールだ。多くのプロジェクトが従う形式はkeepachangelog.comに書かれているものだ。最新バージョンを一番上に、その上にUnreleasedセクションを置き、エントリはAdded、Changed、Deprecated、Removed、Fixed、Securityの下にまとめる。

セクション書く内容例
Unreleasedマージ済みだがまだどのバージョンにも入っていない変更- エクスポートがストリーミングになり、100 MBを超えるファイルでもタイムアウトしなくなった。
Addedユーザーが使える新しい機能- \deploy`の`—dry-run`フラグで、適用せずに計画だけを表示する。`
Changed既存の挙動で、動きが変わったもの- デフォルトのタイムアウトを30秒から60秒に引き上げた。
Deprecatedまだ動くが、削除が予定されているもの- \legacyAuth()`は3.0で削除される。`auth()`を使うこと。`
Removedこのバージョンでなくなったもの- Node 16のサポートを終了した。
Fixedユーザーが遭遇し得たバグ- ハイフンを含むクエリで検索が失敗しなくなった。
Security読者が今日アップグレードすべき修正- 静的ファイルハンドラのパストラバーサルを修正した(CVEは申請中)。

CHANGELOG.mdとは何か

プロジェクトの人間向けの履歴を、バージョンごとに一つずつ、コードと一緒に出荷されるようコードの隣に置いたものだ。git logとは読者と選び方が違う。gitログは書いた本人たちのためにすべてのコミットを記録するが、チェンジログはユーザーが気づくであろう変更を、それを書いていない人のために記録する。内部変数の名前を変えたコミットにチェンジログの行はない。デフォルトのタイムアウトを変えたコミットには、差分が一文字でも行がある。

ファイルがその名前でリポジトリのルートにあるのは、ツールがそこを探すからだ。GitHubはリポジトリのページからリンクし、npmとPyPIはパッケージに含まれていれば表示し、release-pleaseやsemantic-releaseのようなリリースツールはその場で読み書きする。小文字のchangelog.mdやCHANGES.mdも人が読む分には問題ないが、正式な名前しか探さないツールもある。

完全なCHANGELOG.mdはどんな見た目か

短くて正しい例のほうが、長い説明より価値がある。この例はKeep a Changelog 1.1.0のレイアウトに従い、番号にはセマンティックバージョニングを使っている。

# Changelog

このプロジェクトの注目すべき変更はすべてここに記載する。
形式: Keep a Changelog。バージョン: Semantic Versioning。

## [Unreleased]

### Added
- `deploy`の`--dry-run`フラグで、適用せずに計画だけを表示する。

## [2.3.1] - 2026-10-01

### Fixed
- ハイフンを含むクエリで検索が失敗しなくなった。2.3.0から
  壊れていた。

### Security
- 静的ファイルハンドラのパストラバーサルを修正した。ユーザーが
  アップロードしたファイルを配信しているなら今日アップグレードすること。

## [2.3.0] - 2026-09-18

### Added
- ストリーミングエクスポート。100 MBを超えるファイルでも
  タイムアウトしなくなった。

### Deprecated
- `legacyAuth()`はまだ動くが3.0で削除される。
  `auth()`を使うこと。

[Unreleased]: https://github.com/acme/tool/compare/v2.3.1...HEAD
[2.3.1]: https://github.com/acme/tool/compare/v2.3.0...v2.3.1
[2.3.0]: https://github.com/acme/tool/compare/v2.2.0...v2.3.0

価値の大半は四つの細部にある。すべてのバージョンにISO形式の日付があるので、読者は自分の問題が始まった時期と突き合わせられる。各バージョンの見出しは比較ビューへのリンクなので、完全な差分まで一クリックだ。修正には、どのバージョンで壊れたかが書いてある。そしてSecurityセクションは独立しているので、「今すぐアップグレードが必要か」を探している人が数秒で見つけられる。

CHANGELOG.mdはどう最新に保つか

変更と同じプルリクエストでUnreleasedの下に行を書き、リリース時にそのセクションをバージョンの見出しへ移す。方法はそれで全部だ。ファイルが古くなるのは、行を後から別の人が、リリース時に、自分が書いたのではないコミットメッセージの一覧から書くときだ。

習慣を根付かせるものが二つある。一つ目は、src/に触れているのにチェンジログに触れていないプルリクエストを落とすCIのチェックで、ユーザーに見える影響のない変更のためにスキップ用のラベルを用意する。GitHub Actionとしてのチェンジログチェックに40行の版がある。二つ目は、Unreleasedをバージョンと日付に一つのコマンドで書き換えるリリース手順で、誰も手作業を覚えておかなくて済む。チェンジログは誰が書くかは、その行が誰の仕事かをチームがどう決着させるかを扱っている。

チェンジログはコミットから生成すべきか

生成すれば完全な下書きは手に入るが、チェンジログは手に入らない。conventional commitsの上に作られたツールや、release-pleaseのようなリリース自動化は、feat:、fix:、BREAKING CHANGE:の接頭辞を読んで、すべてのプルリクエストにリンクが付いた分類済みのリストを作る。リストの質はコミットの件名の質で決まり、コミットの件名はコードを説明している。

現実的な落としどころは、生成してから編集することだ。ツールにコミットからUnreleasedセクションを作らせ、リリースのプルリクエストでユーザーが読む行を書き直す。関数名ではなく症状を、変更されたファイルではなく移動した設定を。Conventional Commitsからチェンジログへがそのパイプラインを順に説明しており、ブラウザ上のチェンジログジェネレーターなら、何もインストールせずに貼り付けたgit logから下書きを得られる。

CHANGELOG.mdに書くべきでないものは何か

内部のリファクタ、挙動の変わらない依存関係の更新、テストだけのコミット、CI設定、フォーマットの変更だ。これらはgitの履歴にあればよく、必要な人はそこで見つけられる。含めると重要な行が埋もれ、読者はこのファイルを読み飛ばすようになる。

もう一つ省くべきは、変更のマーケティング版だ。「爆速のエクスポート」は読者が確かめられることを何も伝えない。「エクスポートがストリーミングになり、100 MBを超えるファイルでもタイムアウトしなくなった」は伝える。このファイルはリファレンス文書であり、口調もそれに合わせる。短い行、具体的な名詞、すべてにバージョンか日付を。Keep a Changelog、実践編は仕様のうちチームが最も落としがちな部分を扱い、チェンジログのファイル形式は、Markdownファイルの隣にJSONやYAMLのソースを置く価値がいつ出るかを扱っている。

チェンジログページのある製品にも、このファイルは必要か

ライブラリには必要だ。パッケージレジストリが表示するのも、開発者がオフラインで読むのもこのファイルだからだ。インストールできる成果物のないSaaS製品は、ユーザーがリポジトリを見ることがないので、ページだけでもやっていける。多くのチームは両方を運用している。ファイルをエンジニアリングの記録に、そこから書き起こした公開のチェンジログページをより広い読者向けにし、詳細はチェンジログとリリースノートの違いが説明する分け方で振り分ける。ページをファイルから作るなら、ファイルを唯一の情報源にしてページを生成し、編集する場所を一つにしておく。

FAQ

CHANGELOG.mdとリリースノートの違いは何か? チェンジログは、注目すべきすべての変更を記した継続的で完全な記録で、リポジトリに置かれる。リリースノートは一つのリリースについてのメッセージで、より短く、広い読者向けに書き直されることが多い。多くのプロジェクトは、あるバージョンのチェンジログのセクションをそのままリリースノートとして公開している。

CHANGELOG.mdはどこに置くべきか? リポジトリのルートに、正確にその名前で。GitHub、パッケージレジストリ、リリースツールがそこを探すからだ。モノレポではパッケージごとに一つ、それぞれのパッケージのマニフェストの隣に置く。

CHANGELOG.mdはgitのコミットから生成すべきか? 下書きを生成し、ユーザーが読む行を編集する。コミットメッセージはコードの変更を説明し、チェンジログはユーザーが気づくことを説明する。conventional-changelogやrelease-pleaseのようなツールは良い出発点を作ってくれる。

すべてのコミットにチェンジログのエントリは必要か? いいえ。プロジェクトのユーザーが気づき得る変更だけだ。新機能、挙動の変更、非推奨化、削除、修正、セキュリティパッチ。リファクタ、テストの変更、CIの編集はgitの履歴に留める。


この記事の技術的な記述は第三者による確認を受けていません。誤りがあればお知らせください。修正します。

changeloopの関連ページ: changelogジェネレーター, changelogの例

changeloop
ループを閉じるchangelogを作っているチームです。ユーザーが何かを求め、あなたのチームがそれを届け、求めた人がそれを知る。