Semantic Versioning を考える

少し前に Wasmtimeのメジャーバージョンが上がるのが早くてびっくりした話 が投稿されました.

今回はそれに関連してバージョンのつけ方の一つであるセマンティックバージョニング (Semantic Versioning) のお話です.

Semantic Versioning とは

先ほど書いたように Semantic Versioning (以下 SemVer と表記) はバージョンのつけ方です.

そのつけ方は, 公式の概要より,

 バージョンナンバーは、メジャー.マイナー.パッチ とし、バージョンを上げるには、

  1. APIの変更に互換性のない場合はメジャーバージョンを、
  2. 後方互換性があり機能性を追加した場合はマイナーバージョンを、
  3. 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。

 プレリリースやビルドナンバーなどのラベルに関しては、メジャー.マイナー.パッチ の形式を拡張する形で利用することができます。

https://semver.org/lang/ja/

となっています.

例として, 0.1.0 や 1.0.0, 3.3.4 のような形が SemVer として基本的になり, そこから上述の規則に従って, バージョンを上げていきます.

どうしてこのようにしたのかや具体的な仕様書は上記サイトを参照することとして, 今回は SemVer そのものについて考えていきます.

Semantic Versioning 2.0.0

おそらくこのサイトを見たときに最初に目に入るタイトル “Semantic Versioning 2.0.0” を見て気づく方もいるかもしれません.

Semantic Versioning 2.0.0

はい, SemVer 自体一度, メジャーアップデート (後方互換性のないアップデート) をしています.

なので, 元となった, というより最初のメジャーバージョンである 1.0.0 があります.

SemVer の文書は GitHub のリポジトリ (https://github.com/semver/semver) があるのでそこから 1.0.0 と 2.0.0 の diff を取ってみることとします.

diff: https://github.com/semver/semver/compare/v1.0.0…v2.0.0

diff の量はそこまで多くないですが, (私が見た限り) 主な変更は以下の通りです:

・誤字の修正 (must → MUST など)

・一部 (微々たる) 文言の追加, 変更

・ Sumary (概要) の追加

・Tagging Specification (SemVerTag) 項の削除

・プレリリースバージョンに関する文言の変更

・ビルドメタデータに関する文言の追加

SemVer はメジャーアップデートをしているということなので, この中で SemVer 1.0.0 と後方互換性のない変更があったということが発生したということになります.

実際どういう理由で 2.0.0 にしたのかの議論は, 時間がそこまでなかったので探し出せていない (ごめんなさい) ので, 憶測となりますが, “プレリリースバージョンに関する文言の変更” が後方互換性を失うと判断され, 2.0.0 となったと考えています.

変更の中身は大雑把な要約になりますが,

SemVer 1.0.0: “プレリリースバージョンを示す場合, パッチバージョンの直後にハイフンのみで区切って識別子を追加して表現してもよい (MAY)” e.g.) 1.0.0-alpha1, 1.0.0-beta1, 1.0.0-beta2, 1.0.0-rc1

SemVer 2.0.0: “プレリリースバージョンを示す場合, パッチバージョンの直後にハイフンとドットで区切って識別子を追加して表現してもよい (MAY)” e.g.) 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

(太字は筆者強調)

例が一番わかりやすいですが, SemVer 1.0.0 で表現された 1.0.0-alpha1 が SemVer 2.0.0 では 1.0.0-alpha.1 とする必要となり, SemVer 1.0.0 表記では SemVer 2.0.0 の仕様書違反となっています.

SemVer 1.0.0 表記では SemVer 2.0.0 の仕様書を満たさないという点で後方互換性を失ったと考え, SemVer 1.1.0 のような変更ではなく SemVer 2.0.0 になったと考えています.

SemVer に実際に合わせるべきか

実際に, ソフトウェア開発を行う上でバージョニングは一つの問題となるので, SemVer に合わせるというのは一つの合理的な選択肢となります.

しかし, SemVer にあっていないバージョニングは実際多く存在しており, 特に .NET あたりのバージョニングは 1.0.0.0 というバージョン表記が多い印象です (記憶が正しければ, Visual Studio の .NET のプロジェクトでは 1.0.0.0 が初期設定になっているはずです).

また, 1.0.0 → 2.0.0 の変更で書いたプレリリースバージョンに関する仕様はついつい見落としがちで, 自分の場合, “1.0.0-alpha1” みたいについつい書いてしまいます.

また, SemVer にはバージョン制約についての文言がないので, その部分でも問題が発生しています.

(ここらへんのお話は, Semantic Versioningの闇 (外部個人ブログ) のほうが詳しいと思います.)

長くなりましたが, 結局, SemVer に合わせるか合わせないかと問われると私自身は合わせるべきだと考えています.

コメントを残す