セマンティック・バージョニングしたい(commitizen

$ cz commit
$ cz changelog --increment
$ cz bump

commitizenはGitを使ったバージョン管理をサポートしてくれるパッケージです。 コマンド名はczです。 cz サブコマンドするだけで、セマンティック・バージョニングを簡単化できます。

インストールしたい

  • pipでインストール

$ pip3 install commitizen
$ which cz

注釈

同じ名前のnpmパッケージがあります。 自分がどちらを使っているのか、混乱しないようにしましょう。

  • pipxでインストール

$ pipx install commitizen
$ which cz
~/.local/bin/cz
  • poetryでインストール

$ poetry add commitizen --group dev

Poetryを使ってチームで開発している場合は、開発環境にインストールしておくとよいかもしれません。 commitizenはパッケージでは直接使わないため、 devグループに追加するとよいと思います。

初期化したい(cz init

1$ cd プロジェクト名
2$ cz init

cz initcommitizenが使えるようにプロジェクトを初期化できます。 ターミナルに表示されるダイアログにしたがって矢印キーで選択すると、設定ファイルが作成されます。

Pythonパッケージを開発している場合はpyproject.tomlに設定を追加してまとめることができます。 その他の場合は、自分の好みの形式を選択すればよいと思います。 僕は.cz.tomlを選択する場合が多いです。

生成された設定ファイルは次のようになっていました。 最近のPythonパッケージは(暗黙の)ルールとして [tool.パッケージ名]の下に設定を書くようになっています。 (ただの慣習なのか、それを定義したPEPが存在するかは未確認です)

1[tool]
2[tool.commitizen]
3name = "cz_conventional_commits"
4version = "0.0.1"
5tag_format = "$version"

コミットしたい(cz c

$ git add ステージしたいファイル名
$ cz commit
$ cz c

czにステージするためのコマンドはないためgit addでステージします。

ステージしたファイルがある状態で、git commitの代わりにcz commit(もしくはcz c)でコミットを作成します。

プロンプトが表示されるので、聞かれた内容に沿って情報を選択/入力するとコミットメッセージができあがります。

コミットメッセージのテンプレートはcz infoもしくはcz schema、サンプルはcz exampleで確認できます。

変更ログしたい(cz changelog

// 変更ログを作成(すべてのログ)
$ cz changelog
$ cz ch

// 前回からの差分ログ
$ cz changelog --incremental

// 標準出力で確認
$ cz changelog --dry-run

cz changelog(もしくはcz ch)で、これまでのコミットログを使って変更ログ(changelog)を生成できます。 デフォルトのファイル名はCHANGELOG.mdです。 ファイルがすでに存在する場合は上書きされます。 --file-nameオプションで変更できます。

--incrementオプションで、前回からの差分を追記できます。 このオプションの使用はデフォルトにするとよいと思います。

--dry-runオプションで事前確認できます。 ファイルに保存せず、標準出力に表示されます。

バージョンアップしたい(cz bump

1$ cz bump --changelog --check-consistency
2$ cz bump -ch -cc

cz bumpで、これまでのコミットの内容/種類をベースに semverに沿ったバージョン番号のタグを作成し、 設定ファイル内のバージョン番号を更新できます。 プログラムの開発にひと区切りついたら、タグをつけましょう。

-chオプションを使うと、CHANGELOG.mdを更新できます。 バージョンアップしたり、変更履歴をまとたりする作業はなかなか大変ですが、一発でやってくれるのでとても助かります。

注釈

使い始めてみるとすぐに気が付くと思いますが、 バージョンアップが先か、CHANGELOGの整理が先か問題があります。 僕はバージョンアップをしてから、CHANGELOGを整理することにしています。

バージョン番号を一元管理したい

 1[tool]
 2[tool.commitizen]
 3...
 4version = "バージョン"
 5tag_format = "v$version"
 6version_files = [
 7    # "ファイルのパス:変数名" の形式
 8    "pyproject.toml:version",
 9    "src/__init__.py:__version__",
10    "docs/conf.py:version",
11    "docs/conf.py:release",
12
13]

[tool.commitizen.version_files]"ファイルのパス:変数名"の形式で設定することで、 ソースコードの中にあるバージョン番号も cz bumpでまとめて更新できるようになります。

Pythonの場合、バージョン番号を書くファイルに決まりがありませんが、なんとなく、次のような慣習があります。

  • src/__init__.py:__version__

  • src/__version__.py

また、Sphinxでドキュメントを作成している場合は、 次のパスを設定すればOKです。

  • docs/conf.py:version

  • docs/source/conf.py:version--sepした場合)

せっかくcommitizenを使ってsemver管理しても、 ソースコードの中にバージョン番号が散らばっていたら、 意味がありません。 初期設定のときに追加しておくとよいと思います。

フックしたい(commitizen

repos:
- repo: https://github.com/commitizen-tools/commitizen
  rev: v3.29.0
  hooks:
  - id: commitizen
    stages:
    - commit-msg

commitizen (cz)pre-commitに組み込むことができます。 stages: [commit-msg]でコミットメッセージを保存したあとにフックがかかるようにしておきます。