やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

GitHubのタグとセマンティックバージョニング(`v`はつけるべきか?)

 GitHub上ではvをつけるのが一般的らしい。だが、それは無効なセマンティックバージョニングである。GitHubでSemVerを運用するにはどうすればいい?

情報源

背景

  1. PyPIにパッケージを登録してpip installできるようにしたい
  2. GitHubからダウンロードさせることでGitHubAPIからダウンロード数を取得したい
  3. ダウンロードリンクを作成するには、GitHubのrelease機能を使う
  4. release機能はgit tagコマンドで作る
  5. git tagにおけるバージョン値はプレフィクスvをつけるのが一般的(例: v1.0.0
  6. vプレフィクスがついたものは無効なセマンティックバージョニングである

問題

 GitHubでSemVerを運用するにはどうすればいい? プレフィクスvはつけるべきか否か?

結論

 GitHubの文脈ではセマンティックバージョニング(SemVer)を運用できない。ただし、v1.0.0形式で擬似的に運用していると思われる。

 GitHubのタグではプレフィクスvをつけるべき。そのあとにSemVer値を加えたタグ文字列をもって、擬似的にSemVerとして運用する。

問題

 バージョンを正しく大小比較できない。原因はGitHubのタグが文字列であるせい。

  • 期待値: v1.2 < v1.11
  • 実際値: v1.2 > v1.11

 これは数値比較か文字列比較かによる差異である。「期待値」のように数値比較して欲しいのだが、実際のデータは文字列であるため文字列比較されてしまう。結果、4文字目の1より2のほうが大きいため「実際値」の結果となってしまう。

解決不能

 これはGitHubタグ機能における仕様であるため解決不能……。

 0埋めすればいいという妥協案もありそうだが、それはSemVerの仕様から外れてしまうため不可。

一般的な慣習を破れば?

 もちろん可能。ただ、GitHubのタグはあくまで単なる文字列である。バージョン以外のタグ文字列をつけることもできる。そんな中でバージョン用タグを抽出するためにはプレフィクスvを付与したほうが見つけやすい。

 つまり、あくまでタグ機能を使ったバージョニングに過ぎない。バージョニング専用機能でないため、このような残念な結果になる。

  • GitHubのタグは文字列である
  • GitHubのタグはバージョン以外の文字列も与えることができる(運用次第)

Gitはリビジョン管理ツールなのに、バージョニングが文字列でしかできないってどうなの?

 どうしてもこの疑問を禁じ得ない。だが理由はわかる。労力の割に価値がない。

 バージョンの書き方なんて細かいことをいちいち定義するのも面倒だし、それを自動化まで考えると果てしなく大変。その割に得られる成果は小さい。1.0.0のようなバージョン値文字列だけ。

  • バージョンなんて必須でもない
  • あまりに実装が大変
    • 公開APIの変化有無まで見ねば判断できない

環境ごとのバージョニングを考慮した結論

 できるだけ各環境すべてにおける共通値を使うべき。そうするとプレリリース識別子は使わないほうが無難。たとえば1.0.0-alpha.1などにある-alpha.1のようなプレリリース識別子は使わないほうが無難。

0.0.1 # 正式版より前
0.1.0 # 正式版より前
1.0.0 # 正式版

 ただ、非正式版のときは「公開APIが変わるとメジャー値をあげる」ルールが使えない。事実上、ルールがないようなもの。ビルド単位で適当にあげることになりそう。

 GitHubのタグを使うときは上記のバージョン値にプレフィクスvをつける。

対象環境

$ uname -a
Linux raspberrypi 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l GNU/Linux