monorepo の CHANGELOG 生成について調べてみる
前提
- monorepo 構成で複数の package を lerna で管理している
- 今まで fixed mode で管理していたが最近 independent mode に変更した[1]
- fixed mode では CHANGELOG は repository 単位で良かったが independent mode に変更したので CHANGELOG を package 毎に生成し、管理したい
- fixed mode のときは lerna-changelog を使って PR の label をもとに CHANGELOG を生成していた
Refs
-
independent mode に移行した理由はここでは触れない ↩︎
検討するツール
-
lerna
- 今まで使っているので導入コストはない
-
changesets
- graphql-code-generator などで使われているっぽい
観点
- package 毎に CHANGELOG を生成できるか?
- 運用コスト
- commit 規則が必要になったりしないか?
一部のエンジニアだけが作業するなら運用できなくもないが、しばしば Backend メインのエンジニアなども触ることがあるためなるべく新しい規約は導入したくない - リリースオペレーションが複雑になったりしないか?
- commit 規則が必要になったりしないか?
- tool 自体がメンテナンスされているか?
lerna のリリースフロー(&CHANGELOG 生成)について調べてみる
セットアップ
大まかに書く
-
yarn add -D lerna
で lerna を追加する -
yarn lerna init
を実行
ここでlerna.json
が生成されるので、対象となる packages の directory の指定や mode の指定を行う -
yarn lerna ls
を実行し対象の packages が表示されたら多分大丈夫
変更履歴の積み方
lerna-changelog
は PR にラベルをつけることで CHANGELOG を生成していたが、lerna
cli では convensional commit
という命名規則に則って commit を作ることで git の commit log から CHANGELOG を生成し、version を決定する[1]。デフォルトでは angular の preset に従うが、指定することも可能っぽい[2]。
convensional commit に関する詳細は https://www.conventionalcommits.org/en/v1.0.0/ を参照。
いくつか例を上げると以下のような commit の命名を行う
feat(api): allow users to edit their name
fix(bar): fix log formmat
docs: fix typo
リリースの流れ
lerna version
コマンドに --conventional-commits
オプションを渡すと、conventional rule に従って version の bump up と CHANGELOG の生成を行った上でタグを打ち push してくれる。
ちなみに --no-git-tag-version
オプションを渡すとタグは打たずに version の bump up と CHANGELOG の生成のみを行う。
実際に手を動かして試してみる
適当な branch を切って空のファイルを追加した commit を積み、CHANGELOG の生成(version の bump up)を試す。
conventional commit rule に従わなかったとき
+ ## [0.1.1](https://github.com/NotFounds/monorepo-exp/compare/bar@0.1.0...bar@0.1.1) (2022-04-12)
+
+ **Note:** Version bump only for package bar
conventioal commit rule に従わずに、PR のタイトルを convensional rule にして squash merge したとき
+ # [0.2.0](https://github.com/NotFounds/monorepo-exp/compare/foo@0.1.0...foo@0.2.0) (2022-04-12)
+
+ ### Features
+
+ * **foo:** Add file aaa and bbb ([#3](https://github.com/NotFounds/monorepo-exp/issues/3)) ([406d873](https://github.com/NotFounds/monorepo-exp/commit/406d8737956840dbf494b1b32004ed7a54b45d0b))
changesets のリリースフロー(&CHANGELOG 生成)について調べてみる
セットアップ
こちらも大まかに書く。詳細は https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md
-
yarn add -D @changesets/cli
で changesets cli を追加する -
yarn changeset init
を実行
ここで.changesets/
が作られ、中にconfig.json
が生成される -
yarn changeset
を実行し、インタラクティブなプロンプトに対象の packages が表示されていれば多分大丈夫
変更履歴の積み方
yarn changeset add
もしくは yarn changeset
を実行するとインタラクティブなプロンプトで変更履歴を追加したい package の選択と description の記述ができる。変更履歴は .changesets/
以下に適当な名前のファイルとして管理される。
基本的には PR 毎に changeset も一緒に積んでいく形になると思っている。
リリースの流れ
yarn changeset version
コマンドを実行すると .changesets
以下に溜められた変更履歴をもとに version の bump up と CHANGELOG 生成が行われる。
その際に .changesets 以下に溜められていた変更履歴は消されるっぽい。
また、これらの変更は git に staging, commit されないので注意が必要。
npm に publish する場合は予め npm token などの設定を行った上で yarn changeset publish
を実行すると、タグを打ち npm に publish してくれる。
git のタグだけ打ちたい場合は yarn changeset tag
。
publish
tag
どちらのコマンドも git のタグは push してくれないので git push --follow-tags
を自分で実行する必要がある。
所感
- lerna
- convensional commit のルールに従ってさえいれば CHANGELOG は勝手に作られるので記録漏れはなさそう
- commit 単位で CHANGELOG を積むことができるが、我々は普段 PR 単位で CHANGELOG を積んでいるためここの相性が悪い
- PR merge 時に Squash Merge にすることも考えられるが GUI 上でメッセージを編集する必要がありそう?
- changesets
- PR に対して CHANGELOG を必ず積むようにチェックする仕組みを用意できれば記録漏れはなくせそう
- lerna と比較するとリリース時のオペレーションが複雑なのでスクリプトなり自動化しておく必要はありそう
- ファイルとして変更が記録されるのでそれに対するレビューも行いやすそう
一旦 changesets を導入する方針でスクリプト/運用tips 周りを調べてみる
事例1 - changesets/changesets
changesets 自体も changesets を利用している。
package.json を見てみても特殊なことはしていない。
直近の Release Tag に紐づく PR を見てみると先頭に以下のような説明があった。
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
この PR は Changesets の GitHub Actions によって自動生成されたっぽい。
ドキュメント にあるとおり、基本的には GitHub Actions を利用して運用するのが良さそう。
事例2 - dotansimha/graphql-code-generator
graphql-code-generator も changesets を利用している。
こちらも直近の Release PR を見ると Changesets の GitHub Actions を使っているぽい。
changesets/action
既存プロジェクトへの changesets の導入
現在 lerna を持ちているプロジェクトを changesets に移行する。
まずは https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md の手順に従う。
yarn changeset init
を実行すると以下のファイルが作られる。
$ tree .changeset
.changeset
├── README.md
└── config.json
0 directories, 2 files
ここで .changeset/config.json
を覗いてみる。
baseBranch が main
になっているので master
に置き換える。(ここは project による)
cf. https://github.com/changesets/changesets/blob/main/docs/config-file-options.md#basebranch-git-branch-name
{
"$schema": "https://unpkg.com/@changesets/config@2.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
- "baseBranch": "main",
+ "baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": []
}
導入の手順書にもどり、yarn changeset
を実行するとインタラクティブにプロジェクトを選択するプロンプトが出てくる。
Space
で選択し、Enter
で決定する。
ここでは すべての package を選択し、semver は patch
として変更内容を記述する。
例: Generate independently changelogs
yarn changeset status
を実行すると以下のように更新対象の package と、それぞれ major/minor/patch どれが上がるか表示される。
$ yarn changeset status
yarn run v1.22.18
🦋 info Packages to be bumped at patch:
🦋 info
🦋 - パッケージA
🦋 - パッケージB
🦋 ---
🦋 info NO packages to be bumped at minor
🦋 ---
🦋 info NO packages to be bumped at major
✨ Done in 1.02s.
yarn changeset version
を実行することで各 package の version の bump と CHANGELOG 生成が行われる。(この時点では tag は打たれない)
CHANGELOG のフォーマット変更
changesets のデフォルトの設定では、積んだ changesets の変更点が plane text として出力されるだけである。
以下のような plugin を利用することで CHANGELOG にコミットハッシュや GitHub の Pull Request の Link や Auther などの情報を追記することができる。
- https://github.com/changesets/changesets/tree/main/packages/changelog-git
- https://github.com/changesets/changesets/tree/main/packages/changelog-github
自分で script を書くことでより細かく formatting できるが、ここでは changelog-github を用いる。
まず、以下のコマンドを実行し、project に plugin を追加する。
$ yarn add -W -D @changesets/changelog-github
次に以下のように .changeset/config.json
を修正し、format の方法を変更する。
{
"$schema": "https://unpkg.com/@changesets/config@2.0.0/schema.json",
- "changelog": "@changesets/cli/changelog",
+ "changelog": "@changesets/changelog-github",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": []
}
この plugin は yarn changeset version
を実行時に GitHub の Pull Request を探しに行くため、GitHub の Parsonal Access Token(PAT) が必要になる。
GitHub の PAT は ここ から取得することができ、以下のように利用する。
$ GITHUB_TOKEN="<GitHub の PAT>" yarn changeset version
ref
実験用のリポジトリ作りなおした