Go 改版本號規則,主版本號終于支持第三位數字 0 了...
大家好,我是煎魚。
平時我們經常會跟蹤 Go 的版本發布,看看是不是有 BUG,新特性等值得關注的東西,好吸取新的知識和技術跟進,用到自己的日常工作和系統中。
在新的特性、新的資料記錄的映射上,我們也會用版本號來與之關聯,這很常見。
背景
但看 Go 版本號時,會出現一個和其他軟件版本不一樣的神奇現象。那就是 Go 的主要版本號,居然是兩位數:
圖片
說是兩位數,也可以理解。結果你認真一看,會發現是主要版本和次要版本,在兩位數和三位數之間橫跳:
圖片
這時候就會有一個容易引起誤解(理解)的事情。像是開發同學或運維同學部署開發、私有化環境時,問你用的什么版本?
可能大部分同學會直接說用 Go1.20。有了解 Go 版本號規則的人,不知道你到底說的是 Go1.20(第一個版本),還是說要求 Go1.20.x(該大版本的當前最新版本),就會造成明確混淆。
懶得糾結的,一配置,Docker 一拉取。就直接應用到 Go1.20 的第一個版本去了。會錯過許多 Go BUG 本身的修復。
對于許多應用場景來講,這可能影響不是特別大。但對于 Go 是一門對外開源社區運作的編程語言來講,顯然是不合適的。
要不要用 semver 做版本控制
在業內有一個管理版本號的標準:semver。版本格式:“主版本號.次版本號.修訂號”,版本號遞增規則如下:
- 主版本號:當你做了不兼容的 API 修改,將是主版本號的破壞性變更。
- 次版本號:當你做了向下兼容的功能性新增,將是次版本的特性變更。
- 修訂號:當你做了向下兼容的問題修正,將是修復的版本變更。
先行版本號及版本編譯信息可以加到“主版本號.次版本號.修訂號”的后面,作為延伸。并且標準的版本號必須(MUST)采用 X.Y.Z 的格式。
以往在 Go 社區很多人提了很多次,希望 Go 掰過來。用 semver 來管理社區的版本號發布,這樣子最為標準化。
圖片
顯然 Go 是不符合的,為什么呢?因為 Go 并沒有采納這個版本思路,版本號也是用 go 開頭的,例如 runtime.Version()
輸出的結果是:go1.20,或是 go1.20.6。
最重要的是 Go 創始人認為 semver 是理想化的,在互聯網社區的路子上是行不通的,直接就拒絕了。
解決方案
經過多年的折騰,大家也認清了現實。提出了一個有意縮小變更范圍的新提案《build: use a zero for third digit for major release, such as 'go1.21.0'[1]》,爭取解決背景中提到的問題。
圖片
本次僅限只做一個變動,那就是:把 “.0” 加到主版本中。例如以前是 go1.23。現在要變成 go.1.23.0。
在 Go 工具鏈上。例如配套的 go.mod 的 go 行,我后續也是會跟著改變的,主版本時也會多 “.0”,確保兩者保持一致。
這樣的妥協方案,至少可以解決解決大家對 go1.20(以該版本舉例)的理解誤差。明確到底是 1.20.0,還是 1.20.x 的版本。
我們也可以緩解另一派以為 go1.20.0 才是第一個 BUG 修復版本,結果沒想到居然是 go1.20.1。現在會更明確和清晰些。
當然,為此會帶來一些成本。例如:解析 Go 版本號的工具鏈和腳本的改造、文檔、博客、書籍等的更新。但綜合成本來看,改變的成本并不是很大。
總結
目前該提案已經完成審查和 CL,可以說很明確將會進入到 Go 后續版本的使用中。以后主版本將會是 go1.21.0 起,并補充 “.0”,而不再是以前的 go1.21,能夠規避相當一部分的版本混淆問題。
這個問題,說大不大,是比較細微的變更。但在我們的日常工程構建中,是經常會遇到的。為了省事(沒具體看),有的同學會在 Dockerfile 中寫 go1.18,更新版本號也是寫 go1.19、go1.20 等,很少會關注到后面的 BUG 修復版本,這是比較可惜的。
當然,Go 版本號的命名規則不完全統一,本身也是一個比較無奈的事。與此相類似的還有 RC 版本。
Go RC 版本目前的命名規則是:go1.20rc3。社區會建議 go1.20-rc3 的格式規范。但顯然,Go 核心團隊暫時沒打算改。