モノレポのチェンジログ:一つにまとめるか、パッケージごとか
1分で読めます
モノレポは一つのリポジトリの中に、別々にデプロイされる複数のものを収容しており、チェンジログはまず一つの問いに答えなければならない。読者が気にするのはリポジトリなのか、それともその中の特定のパッケージなのか。ほとんどのチームはこれを意図的に決めることがない。一つのリポジトリがあるという理由だけで一つのチェンジログから始め、時間とともにパッケージを追加し、最終的にCLIを使う人が自分の修正をリリースしたエントリを見つけるために、無関係なバックエンドのエントリを四十件も通り過ぎなければならないログに行き着く。正しい形を決めるのはリポジトリの構造ではなく、誰がログを読み、何をすでに探しているかだ。
モノレポのチェンジログは単一リポジトリのものと何が違うのか
単一リポジトリのチェンジログには暗黙の読者がいる。そのリポジトリが構築する唯一のものを使う全員だ。モノレポの読者はパッケージごとに分かれ、同じリポジトリ内のパッケージは、しばしば異なるスケジュールで、異なる利用者に向けて、異なる安定性のレベルで リリースされる。レジストリで公開されるライブラリと内部の管理ツールが同じモノレポに同居し、チェンジログを読む人にとってほとんど共通点がないこともある。
| リポジトリの形 | 典型的な読者 | 合うチェンジログ |
|---|---|---|
| デプロイ可能なアプリが一つ | 製品を使う全員 | リポジトリ全体で一つのログ |
| ライブラリのワークスペース(複数の公開パッケージ) | 特定のパッケージに依存する人 | パッケージごとに一つのログ |
| アプリと内部ツール | 重ならない二つの読者層 | フォルダではなく読者層で分割 |
| アプリと独自のSDK | 製品の利用者と、SDKの統合者 | 二つのログ:製品向けとSDK向け |
すべてのパッケージが独自のチェンジログを必要とするか
独立した読者を持つパッケージだけだ。レジストリで公開されるパッケージは独自のログを必要とする。それをインストールする人にはリポジトリの他の部分を読む理由がなく、LernaやChangesetsのようなモノレポのリリースツールは、パッケージごとのCHANGELOG.mdをそのpackage.jsonのそばに書き出すからだ。同じリポジトリにすでに存在するアプリという単一の利用者を持つ内部ユーティリティは、別のログを必要としない。その変更をそのアプリのエントリに組み込むほうが、チーム外の誰も開かない二つ目のファイルより有用だ。
そのテストは、あるエントリがそもそもチェンジログに属するかどうかを決めるものと同じだ。読者はそれに気づくか、気にかけるか、そしてそれを知って行動できるか。フォルダごとではなくパッケージごとにこれを適用すれば、十二個のパッケージを持つリポジトリは、二つの本物のチェンジログと、それを全く必要としない十個のパッケージに落ち着くこともある。
どのパッケージがどのチェンジログのエントリを引き起こしたかはどうやって分かるのか
各エントリを、コミットがどのファイルに触れたかを後から調べるのではなく、エントリが書かれた瞬間にそのパッケージでラベル付けする。共有された内部ライブラリを修正するコミットは、それに依存するすべてのパッケージでチェンジログのエントリを生む可能性があり、ファイルパスだけではそれらの下流のエントリのどれを読者が本当に見る必要があるかを示せない。「これはパッケージAの利用者には見えて、パッケージBの利用者には見えない」と決められるのは人だけだ。Conventional Commitsは各コミットでパッケージを名指しすることで機械的にここを助けるが、スコープはそれでも下書きしか生まない。あの記事と同じ二層のルールがパッケージごとに当てはまる。正しいスコープを持つ下書きも、そのパッケージの本当の読者に向けて言い換えられる前に、人の手による確認をやはり必要とする。
リポジトリ全体で共有するチェンジログが、単一リポジトリのものには必要ないものは何か
各エントリの一番先頭、説明の前にあるパッケージのラベルだ。それによってログを流し読みする読者は、一度の通過で自分に関係ないものをすべて飛ばせる。そのラベルがなければ共有ログはランダムなフィードのように読め、一つのパッケージに関心のある読者は、どの行が重要かを記憶する以外にそれを絞り込む方法がなく、それを最初の一週間を過ぎても続ける人はいない。
## 2026-09-07
### [cli] 追加
- `acme push --dry-run` は実際に送信せずに、何が送信され
るかを表示する。
### [core] 修正
- 空のボディを返す成功したリクエストで、再試行のバックオフが
もうリセットされなくなった。
二つのエントリ、二つの読者層、見分けるのに一目で済む。Changesets のようなワークフローは、このラベル付けをリリースプロセスに直接組み込む。貢献者は自分の変更のそばに、パッケージのスコープを持つ短いメモを書き、ツールはリリースの瞬間にそれらのメモからパッケージごとのチェンジログとバージョンの跳躍を組み立てる。統合されたコミット履歴から後付けでパッケージの境界を再構築しようとする代わりにだ。
バージョニングはモノレポのチェンジログとどう関わるのか
独立してバージョン管理されるパッケージは、独自のバージョン番号を持つため独自のチェンジログを必要とし、共有チェンジログは「パッケージAが2.1から2.2に上がった一方でパッケージBは1.4のままだった」を、一つのファイルの中の二つのログにならずに表現することはできない。セマンティックバージョニングとあなたのチェンジログは、バージョン番号自体がチェンジログのカテゴリにどうマッピングされるべきかを扱っている。モノレポではそのマッピングをパッケージごとに適用する必要がある。あるパッケージの破壊的変更は、それに依存しない姉妹パッケージにとっての破壊的変更ではないからだ。
多くの内部パッケージから構築されていても、一つの製品を一つのデプロイ可能な単位としてリリースするリポジトリには、この問題はない。パッケージは常に一緒にリリースされるためバージョンを共有し、単一のチェンジログが正しい。
gitタグはモノレポにどう当てはまるのか
gitタグ、リリース、あなたのチェンジログと同じルールが、パッケージごとに適用されて当てはまる。独自のバージョンを持つパッケージは独自のタグの接頭辞を必要とし、典型的には、どのパッケージに属するか言えない裸のv1.4.0ではなくパッケージ名@1.4.0となる。裸のバージョン番号だけでタグ付けされたモノレポは、後になって「cliが2.2をリリースしたときcoreには何が入っていたか」に答えられない。そのタグが実際にどのパッケージに属していたかをディスク上の何も記録していないからだ。
FAQ
モノレポ内のすべてのパッケージに対して別々のチェンジログが必要か? 独立した読者を持つパッケージだけだ。通常はレジストリで公開されるものすべてが該当する。同じリポジトリにすでに存在する一つの内部利用者しか持たないパッケージは、独自のログを維持する代わりに、その利用者のログに組み込むことができる。
チェンジログのエントリを正しいパッケージでラベル付けするのは何か? 変更されたファイルパスの自動スキャンではなく、エントリを書く人が、それを書く瞬間に行うことだ。共有ライブラリの変更は、それに依存する各パッケージで異なるエントリを生む可能性があり、それらの下流のエントリそれぞれが実際に何を言うべきかを決められるのは人だけだ。
モノレポはすべてに対して単一のバージョン番号を使うべきか? 各パッケージが常に他と一緒にリリースされる場合に限る。パッケージがいつか独立して公開されるなら、独立したバージョンが必要になり、独立したバージョンには意味をなすために独立したチェンジログが必要になる。
モノレポのチェンジログツールは人間による編集の工程を置き換えるのか? いいえ。Changesetsのようなツールはリリースの瞬間にパッケージごとのメモを集めて組み立てる作業を自動化する。メモそのものは、貢献者ではなく読者の言葉で書かれ、他のどのチェンジログのパイプラインとも同様に、依然として人の仕事だ。
この記事の技術的な記述は第三者による確認を受けていません。誤りがあればお知らせください。修正します。