tagpr の versionFile がわかりにくかったのでドキュメントPRを出した
tagpr の README を読んでたら、tagpr.versionFile の説明が絶妙にわかりにくくて、何を言ってるのかしばらく悩んだ。せっかくなので AI に実装読ませて、ドキュメント修正する PR を出した。
tagpr の設定項目のひとつに tagpr.versionFile というのがある。元の README の説明はこう。
Versioning file containing the semantic version needed to be updated at release. It will be synchronized with the "git tag".
パッと読んで「ファイルを git tag と同期する」とは書いてあるんだけど、いつ、どっち向きに同期するのかが一切わからん。あと「指定しなかったらどうなるの?」も書いてない。謎。
多くのプロジェクトって、git tag とは別に、ソースの中にもバージョン番号を書いてるじゃんね。
- Ruby なら
*.gemspecのspec.version - Node.js なら
package.jsonの"version" - Python なら
setup.cfgのversion - Go なら
version.goのconst version - Perl なら
Bar.pmのour $VERSION
これらは当然 git tag と一致しててほしい。versionFile はまさにそのファイルを指定する項目で、tagpr がリリースのたびに中身を書き換えて揃えてくれる、ということなんだろうなぁ、とは思っていた。
実装を AI に読ませた。versionfile.go と tagpr.go、tag.go あたり。そしたら README からは読み取れない挙動がいくつか出てきた。
まず「同期」は双方向だった。 タイミングによって向きが逆になる。
- リリースPRを作る/更新するとき → 次バージョンをファイルに書き込む(
bumpVersionFile) - PRがマージされてタグを打つとき → ファイルから読み取ってタグを決める(
retrieveVersionFromFile)
つまりリリースPR上でバージョン番号を手で書き換えると、その値がタグに反映される。マージ時にファイルを正として読むから。これ地味に大事な挙動なのに、README には書いてない。
次に、空欄だと自動検出が走る。 これも書いてなかった。versionFile を未指定にしておくと、tagpr がリポジトリ全体を walk して「versionっぽい文字列 + 現在のバージョン番号」にマッチするファイルを探しに行く。
verReg, err := regexp.Compile(versionRegBase + regexp.QuoteMeta(ver.Naked()))
候補が複数あったら、言語ごとの優先順位で1つ選ぶ。.gemspec → .go → setup.py/cfg → package.json → pom.xml → Cargo.toml → Perl の META.json + lib/*.pm みたいな順。README にある「gemspec, setup.cfg, package.json などがよく使われる」という例示、あれ単なる例じゃなくて実際に検出ロジックにハードコードされてる対象そのものだった。そんなことになってるというのはコード読まなきゃわからぬ。
で、README にある - の意味もここでやっとつながる。
If you do not want to use versioning files but only git tags, specify the "-" string here.
空欄だと自動検出しちゃうので、「ファイルは一切使わず git tag だけで運用したい」なら明示的に - を書いて検出を止める必要がある、という話だった。つまり設定値は実質3状態ある。
| 値 | 挙動 |
|---|---|
| 空欄 | 自動検出が走る |
- |
ファイルを使わない。バージョンはPRラベル(major/minor)から推測 |
| パス | そのファイルを使う。カンマ区切りで複数可 |
この「空欄 = 自動検出」「- = 検出も無効」の対比、コード読むまで全然わからんかった。
というわけで、理解した内容をもとにドキュメントを直した。README と、config.go の中にある同じ説明のコメントブロック、両方を揃えて更新。
追記したポイントはこの2つ。
- 未指定なら自動検出が走ること
- 同期が双方向で、PR上でバージョンを手編集できること
逆に、bumpVersionFile が先頭1箇所しか置換しないとか、検出時にスキップするディレクトリの一覧とか、その辺の細かい実装詳細はあえて入れなかった。設定リファレンスに書くと他の項目と分量のバランスが崩れるので。ドキュメントは網羅よりバランス。
PRはこれ。
https://github.com/Songmu/tagpr/pull/370
ツールのドキュメントって、書いた人にとっては自明でも読む側からは「で、指定しなかったら何が起きるの?」が抜けがちなんだよな。今回まさにそれだった。挙動が分岐する設定項目は、デフォルト(=未指定時)の振る舞いこそ書いてあると助かる。自戒もこめて。
Published: 2026-07-21(Tue) 15:23