semantic-release + git-cz でライブラリを良い感じに Semantic Versioning する
手動でバージョン管理して npm publish
するのが手間なので、eslint-plugin-atomic-design
の作業ついでに、以前より気になってた semantic-release
を導入しました。
適切なフォーマットで書かれた commit log を見て、変更に応じた Semantic Versioning を自動で行います。 release や(npm package なら)npm publish する際に自力で計算する必要がなくなるので、
npm version
+npm publish
GitHub
の ReleaseCHANGELOG.md
生成
上記の様な release 作業自体を CI 連携することで完全自動化できます。また、これに付随して適切な commit をするモチベになります。OSS やるなら(たとえ committer が自分ひとりでも)入れたほうが圧倒的に良いでしょう。
*OSS リポジトリで見たことある感じの、ちゃんとした GitHub release
導入と設定も簡単で、semantic-release-cli
を使えば npm
と GitHub
で必要な Token を発行・取得して (Circle | Travis) CI の環境変数に設定までやってくれます。
で、それを試したら CircleCI に登録するところでコケて死んだので、自力で各サービスの Token 再取得・再生性して環境変数に突っ込み .circleci/config.yml
追記して。結局手作業になりました。紹介しておいて台無しですが、大した手間じゃないんではじめから手作業でいいです。
プラグイン毎に細かい設定もできるのですが、
{
"release": {
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/github",
"@semantic-release/npm",
"@semantic-release/git"
]
}
}
今のところはただ並べただけでいけてます。
機械的にバージョン管理する仕組み上、Conventional commit messages が必須要件になります。決まったフォーマット message をいちいち手書きするのは、ミスったときのことを考えると消耗するので、素直に commitizen
で導入した git-cz
を使うようにしました。特に不便がなく、開発体験が良くなってます。おすすめです。
導入方法
せっかくなんで導入方法書いときます。
1. semantic-release
の準備
semantic-release
をプロジェクトの devDependencies
に install
$ npm i -D semantic-release
Plugin の導入
Plugin list をみて、やりたいことに応じた Token なりを用意します。
-
@semantic-release/commit-analyzer
- commit を解析して、release versioning を行う(大前提ぽい)
-
@semantic-release/release-notes-generator
:- release-note を生成する(
generateNotes
)
- release-note を生成する(
-
generateNotes
の内容からCHANGELOG.md
を生成する- つまり、release-notes-generator に依存
-
- 決定した release version にしたがって、
GitHub release
に publish - commit 内容に含められる、関係 Issue / PullRequest にコメント
- 決定した release version にしたがって、
-
- 決定した release version にしたがって、
npm
にpublish
- 決定した release version にしたがって、
ほかにも色々あります。
-
- 任意の step で任意のシェルコマンドを実行できる
- 正味これ使えば npm でも GitHub などリポジトリ等関係ない操作もできる
Community plugins みると、リリース先の対象が Chrome Web Store - Extension(わかる)、DockerHub(!)、Maven central(!!!!?!?!??!!!) …色々あります。
いくつかの Plugin は依存関係あるので注意。
各連携サービスの Token 取得 & CI の環境変数に設定
上記で導入した Plugin ごとに必要な Token を用意して、利用する CI 側の環境変数に設定します。必要な Token と環境変数名は 各 Plugin のリポジトリの README.md を見てください。
CI の設定
あとは、CI 側で npx semantic-release
を実行するように job の設定をするだけです。
下記は CircleCI の例で、 master
の変更を test して、通ったら release するようにしてます。
この辺、 release branch で運用するなりはお好みで。
# https://github.com/RyoNkmr/eslint-plugin-atomic-design/blob/e3a0fc5646addb1025892d0e4e635306bb51ba44/.circleci/config.yml
# 略
release:
<<: *defaults
steps:
- checkout
- run: npm ci
- run: npx semantic-release
workflows:
version: 2
test_and_release:
jobs:
- test
- release:
requires:
- test
filters:
branches:
only: master
2. git-cz
の導入と設定
commitizen
(git-cz CLI tool) を global install する
commit のフォーマットを作るのは git-cz
で、commitizen
自体はその導入と設定を楽にする CLI tool です。これを global install しておきます。
$ npm install -g commitizen
プロジェクトを commitizen
friendly にする
- もしプロジェクトが
npm
を使ってるなら:
commitizen init cz-conventional-changelog --save-dev --save-exact
yarn
を使ってるなら:
commitizen init cz-conventional-changelog --yarn --dev --exact
やってることは
devDependencies
にcz-conventional-changelog
adapter を追加 & installpackage.json
のconfig.commitizen
に上記 adapter への path を通す
これで、 git cz
すると対話的 UI で commit できるようになります。
利用する
git add
した後に git commit
する代わりに git cz
します。下記のようないい感じのやつがでるはずです:
$ git cz
cz-cli@3.1.1, cz-conventional-changelog@2.1.0
Line 1 will be cropped at 100 characters. All other lines will be wrapped after 100 characters.
? Select the type of change that you're committing: (Use arrow keys)
❯ feat: A new feature
fix: A bug fix
docs: Documentation only changes
style: Changes that do not affect the meaning of the code (white-space, formatting, missin
g semi-colons, etc)
refactor: A code change that neither fixes a bug nor adds a feature
perf: A code change that improves performance
(Move up and down to reveal more choices)
@ymmooot の nuxt-jsonld
手伝ってて気づいたんですが、OSS にするなら git commit
hook したいので設定すると吉っぽいです。
git hook できれば何でも良いんですが、ここでは husky
を使います。
$ npm i -D husky
あとは設定するだけ
"husky": {
"hooks": {
"prepare-commit-msg": "exec < /dev/tty && git cz --hook"
}
}
もしくは、
直接 .git/hooks/prepare-commit-msg
を書いても OK
#!/bin/bash
exec < /dev/tty
npx git-cz --hook
実行権限をつけるのを忘れずに
$ chmod 755 .git/hooks/prepare-commit-msg
あとは普通に git commit
すると git cz
が勝手に発動します。
余談
-
設定足りなくて
CHANGELOG.md
生成したのに push し損ねててはずかしい- 足したから多分次回 release でなおるはず。試さないとわからん
-
semantic-release-cli
は inquirer てやつ使ってyeoman
みたいなのやってる- って調べたら
yeoman
自体inquirer
使ってた
- って調べたら
- グッパイ平成、ハロー令和