セマンティックバージョニングがよくわかるクイズ12問

# はじめに
パッケージ管理ツール初学者向けにセマンティックバージョニングの説明会を実施しました。
クイズ形式にしたところ、好評だったのでその時の資料を公開します。

クイズに答えていけば、セマンティックバージョニングの仕組みが理解できるようになると思います！

ぜひやってみてください！



## セマンティックバージョニング(semantic versioning)とは？

バージョン番号の付け方の1種です。SemVerと略されたりします。

Node.jsのパッケージ管理ツールの1種であるnpmが、セマンティックバージョニングに準拠していることで有名です。
https://docs.npmjs.com/about-semantic-versioning

セマンティックバージョニングの詳しい仕様は、以下のページをご覧ください。
https://semver.org/lang/ja/

本記事では上記のページを `仕様書` と呼ぶことにします。



# セマンティックバージョニングクイズ

## 問1：以下の中でセマンティックバージョニングとして正しいバージョン表記はどれですか？

- [ ] 0.01.0
- [ ] 0.1.3.1
- [ ] 1-1-0
- [ ] 1.2.a
- [ ] 3,9,2
- [ ] 2.-1.3
- [ ] 0.11.0

<details><summary>正解と解説</summary><div>
正解： **0.11.0**

仕様書には以下のような記述があります。

> 通常のバージョンナンバーは、X.Y.Zの形式にしなければなりません（MUST）。このときX、Y、Zは非負の整数であり（MUST）、各数値の先頭にゼロを配置してはなりません（MUST NOT）。Xはメジャーバージョン、Yはマイナーバージョン、Zはパッチバージョンを表します。各バージョンは数値的にバージョンアップしなければなりません（MUST）。例：1.9.0 -> 1.10.0 -> 1.11.0。

各選択肢の解説は以下の通りです。

- [ ] 0.01.0 ： 各数値の先頭にゼロを配置してはなりません（MUST NOT）ので誤りです。
- [ ] 0.1.3.1 ： X.Y.Zの形式にしなければなりません（MUST）ので誤りです。
- [ ] 1-1-0 ： X.Y.Zの形式にしなければなりません（MUST）ので誤りです。
- [ ] 1.2.a ： X、Y、Zは非負の整数である（MUST）ので誤りです。
- [ ] 3,9,2 ： X.Y.Zの形式にしなければなりません（MUST）ので誤りです。
- [ ] 2.-1.3 ： X、Y、Zは非負の整数である（MUST）ので誤りです。
- [x] 0.11.0 ： 正解です。

</div></details>



## 問2：1.1.9でバグが発生しました！バグのみを修正したら、バージョンはいくつになりますか？
- [ ] 1.1.9.1
- [ ] 1.1.10
- [ ] 1.2.0

<details><summary>正解と解説</summary><div>

正解： **1.1.10**

仕様書には以下のような記述があります。

> パッチバージョン Z （x.y.Z | x > 0）は、後方互換性を保ったバグ修正を取り込んだ場合のみ、上げなければなりません（MUST）。バグ修正とは間違った振る舞いを修正する内部の変更のことを指します。

各選択肢の解説は以下の通りです。

- [ ] 1.1.9.1 ： X.Y.Zの形式にしなければなりません（MUST）ので誤りです。
- [x] 1.1.10 ： バグだけを修正したので、パッチバージョンを上げたこちらが正解です。
- [ ] 1.2.0 ： 機能性を追加したわけではないので、マイナーバージョンは上げません。

</div></details>



## 問3：1.2.5のWebAPIに新しいパス（新機能）を追加しました！既存の機能の仕様は変わっていません。バージョンはいくつになりますか？
- [ ] 1.2.5.1
- [ ] 1.2.6
- [ ] 1.3.0
- [ ] 1.3.5
- [ ] 2.0.0

<details><summary>正解と解説</summary><div>

正解： **1.3.0**

仕様書には以下のような記述があります。

> マイナーバージョン Y （x.Y.z | x > 0）は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません（MUST）。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません（MUST）。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです（MAY）。その際にパッチレベルの変更も含めてもよいです（MAY）。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）。

各選択肢の解説は以下の通りです。

- [ ] 1.2.5.1 ： X.Y.Zの形式にしなければなりません（MUST）ので誤りです。
- [ ] 1.2.6 ： バグを修正したわけではないので、パッチバージョンは上がりません。
- [x] 1.3.0 ： 機能性を追加したので、マイナーバージョンを上げたこちらが正解です。
- [ ] 1.3.5 ： マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）ので、こちらは誤りです。
- [ ] 2.0.0 ： 後方互換性は保たれているので、メジャーバージョンは上げません。こちらは誤りです。

</div></details>



## 問4：開発初期段階で、最初のバージョンにはどれがもっとも無難ですか？（慣習の側面もあります）
- [ ] 0.0.0
- [ ] 0.0.1
- [ ] 0.1.0
- [ ] 1.0.0

<details><summary>正解と解説</summary><div>

正解： **0.1.0**

仕様書には以下のような記述があります。

> ### 0.y.zのような初期の開発フェーズにおけるバージョンの取り扱いはどのようにすべきでしょうか？
>　一番簡単な方法は0.1.0からで開発版をリリースし、その後のリリースのたびにマイナーバージョンを上げていけばよいでしょう。

各選択肢の解説は以下の通りです。

- [ ] 0.0.0 ： このバージョンでも実害はありませんが、仕様書には0.1.0から開始すると記載がありますので、不正解です。
- [ ] 0.0.1 ： このバージョンでも実害はありませんが、仕様書には0.1.0から開始すると記載がありますので、不正解です。
- [x] 0.1.0 ： 仕様書に「0.1.0からで開発版をリリース」と記載があるので、こちらが無難です。
- [ ] 1.0.0 ： パブリックに公開したわけではないので、1.0.0にはなりません。

</div></details>



## 問5：1.2.7をリファクタリングして処理速度が、2倍になりました！APIの仕様は変わっていません。バージョンはいくつになりますか？
- [ ] 1.2.7のまま
- [ ] 1.2.7.1
- [ ] 1.2.8
- [ ] 1.3.0
- [ ] 2.0.0

<details><summary>正解と解説</summary><div>

正解： **1.2.7**または**1.3.0**のどちらか

仕様書には以下のような記述があります。

> マイナーバージョン Y （x.Y.z | x > 0）は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません（MUST）。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません（MUST）。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです（MAY）。その際にパッチレベルの変更も含めてもよいです（MAY）。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）。

各選択肢の解説は以下の通りです。

- [x] 1.2.7のまま ： 機能性が変わっていないので、バージョンを変更しないという考えは間違いではありません。こちらは正解の1つです。
- [ ] 1.2.7.1 ： X.Y.Zの形式にしなければなりません（MUST）ので誤りです。
- [ ] 1.2.8 ： バグを修正したわけではないので、パッチバージョンは上げません。こちらは誤りです。
- [x] 1.3.0 ： プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです（MAY）ので、こちらも正解の1つです。
- [ ] 2.0.0 ： 後方互換性は保たれているので、メジャーバージョンは上がりません。

</div></details>



## 問6：現在、スマホアプリとWebAPIを同時に開発しています。WebAPIはそのスマホアプリからしか利用されていません。現在のWebAPIのバージョンは0.3.5です。この度、スマホアプリがAppStoreにリリースされました！WebAPIのバージョンはいくつにしますか？
- [ ] 0.3.5のまま
- [ ] 0.3.6
- [ ] 0.4.0
- [ ] 1.0.0

<details><summary>正解と解説</summary><div>

正解： **0.3.5**または**1.0.0**

仕様書には以下のような記述があります。

> バージョン1.0.0はパブリックAPIを定義します。このリリース後のバージョンナンバーの上げ方に関しては、パブリックAPIがどのくらい変更されるのかによって決まります。

> ### 1.0.0のリリースはいつすべきでしょうか？
> もし既にプロダクション用途であなたのソフトウェアが利用されているのなら、それは1.0.0であるべきでしょう。またもし安定したAPIを持ち、それに依存しているユーザーが複数いるのなら、それは1.0.0であるべきでしょう。もし後方互換性について多大な心配をしているのなら、それは1.0.0であるべきでしょう。

各選択肢の解説は以下の通りです。

- [x] 0.3.5のまま ： 機能性が変わっていないので、バージョンを変更しないという考えは間違いではありません。こちらは正解の1つです。
- [ ] 0.3.6 ： バグを修正したわけではないので、パッチバージョンは上げません。こちらは誤りです。
- [ ] 0.4.0 ： 機能性が変わっていないので、マイナーバージョンは上げません。こちらは誤りです。
- [x] 1.0.0 ： AppStoreにリリースされたということは、プロダクション用途でWebAPIが利用されているということですので、1.0.0にすべきという記載が仕様書にあります。こちらも正解の1つです。

</div></details>



## 問7：1.12.6のとある機能の仕様を変更しました！後方互換性はなくなりました。バージョンはいくつになりますか？
- [ ] 1.12.7
- [ ] 1.13.0
- [ ] 2.0.0
- [ ] 2.1.0
- [ ] 2.12.0

<details><summary>正解と解説</summary><div>

正解： **2.0.0**

仕様書には以下のような記述があります。

> メジャーバージョン X （X.y.z | X > 0）は、パブリックAPIに対して後方互換性を持たない変更が取り込まれた場合、上げなければなりません（MUST）。その際にマイナーおよびパッチレベルの変更も含めてもよいです（MAY）。メジャーバージョンを上げた際には、パッチおよびマイナーバージョンを0にリセットしなければなりません（MUST）。

各選択肢の解説は以下の通りです。

- [ ] 1.12.7 ： バグ修正の有無にかかわらず、後方互換性を持たない変更が取り込まれた場合、メジャーバージョンを上げなければなりません。こちらは誤りです。
- [ ] 1.13.0 ： 後方互換性を持たない変更が取り込まれた場合、メジャーバージョンを上げなければなりません。こちらは誤りです。
- [x] 2.0.0 ： 後方互換性を持たない変更が取り込まれた場合、メジャーバージョンを上げなければなりません。こちらが正解です。
- [ ] 2.1.0 ： メジャーバージョンを上げた際には、パッチおよびマイナーバージョンを0にリセットしなければなりません（MUST）のでこちらは誤りです。
- [ ] 2.12.0 ： メジャーバージョンを上げた際には、パッチおよびマイナーバージョンを0にリセットしなければなりません（MUST）のでこちらは誤りです。

</div></details>



## 問8：0.3.6のとある機能の仕様を変更しました！後方互換性はなくなりました。ただ、現在は開発初期フェーズであり、直近では仕様がコロコロ変わる可能性が高いです。バージョンはいくつにするのが無難ですか？
- [ ] 0.4.0
- [ ] 1.0.0

<details><summary>正解と解説</summary><div>

正解： **0.4.0**

仕様書には以下のような記述があります。

> メジャーバージョンのゼロ（0.y.z）は初期段階の開発用です。いつでも、いかなる変更も起こりえます。この時のパブリックAPIは安定していると考えるべきではありません。

> ### 1.0.0のリリースはいつすべきでしょうか？
> もし既にプロダクション用途であなたのソフトウェアが利用されているのなら、それは1.0.0であるべきでしょう。またもし安定したAPIを持ち、それに依存しているユーザーが複数いるのなら、それは1.0.0であるべきでしょう。もし後方互換性について多大な心配をしているのなら、それは1.0.0であるべきでしょう。

各選択肢の解説は以下の通りです。

- [x] 0.4.0 ： 開発初期段階では、メジャーバージョンはゼロのままですので、代わりにマイナーバージョンを挙げるのが無難です。
- [ ] 1.0.0 ： 開発初期段階では、メジャーバージョンはゼロですので、1.0.0にはなりません。

</div></details>




## 問9：1.5.2にバグが見つかりました！バグを修正して、ついでに、新しい機能も追加しました！既存の機能の仕様は変わっていません。バージョンはいくつになりますか？
- [ ] 1.5.3
- [ ] 1.6.0
- [ ] 1.6.1
- [ ] 2.0.0

<details><summary>正解と解説</summary><div>

正解： **1.6.0**

仕様書には以下のような記述があります。

> マイナーバージョン Y （x.Y.z | x > 0）は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません（MUST）。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません（MUST）。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです（MAY）。その際にパッチレベルの変更も含めてもよいです（MAY）。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）。

各選択肢の解説は以下の通りです。

- [ ] 1.5.3 ： バグ修正の有無にかかわらず、機能性が上がった場合は、マイナーバージョンを上げます。こちらは誤りです。
- [x] 1.6.0 ： 機能性が追加されたので、マイナーバージョンを上げます。こちらが正解です。
- [ ] 1.6.1 ： マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）ので誤りです。
- [ ] 2.0.0 ： 後方互換性は保たれているので、メジャーバージョンは上げません。

</div></details>




## 問10：2.6.3をリリースした直後にバグが見つかりました！30秒でバグ修正版をリリースしました！バージョンはいくつになりますか？
- [ ] 2.6.3のまま
- [ ] 2.6.4

<details><summary>正解と解説</summary><div>

正解： **2.6.4**

仕様書には以下のような記述があります。

> 一度パッケージをリリースしたのなら、そのバージョンのパッケージのコンテンツは修正してはなりません（MUST NOT）。いかなる修正も新しいバージョンとしてリリースしなければなりません（MUST）。

上記にしたがうと、例え、30秒で修正したとしても、2.6.4が正解です。


</div></details>



## 問11：1.14.3のとあるAPIを廃止しました。バージョンはいくつにしますか？
- [ ] 1.14.4
- [ ] 1.15.0
- [ ] 2.0.0

<details><summary>正解と解説</summary><div>

正解： **2.0.0**

仕様書には以下のような記述があります。

> マイナーバージョン Y （x.Y.z | x > 0）は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません（MUST）。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません（MUST）。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです（MAY）。その際にパッチレベルの変更も含めてもよいです（MAY）。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）。

各選択肢の解説は以下の通りです。

- [ ] 1.14.4 ： 後方互換性が保たれていないので、メジャーバージョンを上げていないこちらは不正解です。
- [ ] 1.15.0 ： 後方互換性が保たれていないので、メジャーバージョンを上げていないこちらは不正解です。
- [x] 2.0.0 ： 後方互換性が保たれていないので、メジャーバージョンを上げてるこちらは正解です。

</div></details>



## 問12：1.11.1のとあるAPIを廃止予定としました。まだ廃止にはしませんが、廃止予定となる旨をドキュメントやコードに記載してリリースします。バージョンはいくつになりますか？
- [ ] 1.11.1のまま
- [ ] 1.11.2
- [ ] 1.12.0
- [ ] 2.0.0

<details><summary>正解と解説</summary><div>

正解： **1.12.0**

仕様書には以下のような記述があります。

> マイナーバージョン Y （x.Y.z | x > 0）は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません（MUST）。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません（MUST）。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです（MAY）。その際にパッチレベルの変更も含めてもよいです（MAY）。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません（MUST）。

各選択肢の解説は以下の通りです。

- [ ] 1.11.1のまま ： APIを廃止予定としたので、マイナーバージョンを上げていないこちらは不正解です。
- [ ] 1.11.2 ： APIを廃止予定としたので、マイナーバージョンを上げていないこちらは不正解です。
- [x] 1.12.0 ： APIを廃止予定としたので、マイナーバージョンを上げているこちらは正解です。
- [ ] 2.0.0 ： 後方互換性が保たれてるので、メジャーバージョンを上げてるこちらは不正解です。


</div></details>



# さいごに

クイズ形式にしたら私の職場では結構盛り上がりました。ぜひみなさんも同僚とクイズをやってみてください。

もし、クイズの内容に間違いがある場合は、ご指摘をお願いします。

おつかれさまでした。