1. 程式人生 > >關於軟體版本號的問題 軟​件​版​本​號​命​名​規​則

關於軟體版本號的問題 軟​件​版​本​號​命​名​規​則

關於軟體版本號的問題

   完全的版本號定義,分三項::<主版本號>.<次版本號>.<修訂版本號>,如 1.0.0。

1.版本號升級原則:

   主版本號:功能模組有大的變動,比如增加多個模組或者整體架構發生變化。  

   次版本號:和主版本相對而言,次版本號的升級對應的只是區域性的變動。但該區域性的變動造成了程式和以前版本不能相容,或者對該程式以前的協作關係產生了破壞,或者是功能上有大的改進或增強。  

   修訂版本號:區域性的變動,主要是區域性函式的功能改進,或者bug的修正,或者功能的擴充。

------------------------------------------------------------------------------------

   各種軟體的版本號是怎麼確定的,怎樣的跨越才能算是由bate到正式版?原則上,自第一個穩定版本釋出後,修訂版本號會經常性改動,而次版本號則依情況作改動,主版本號改動的頻率很低,除非有大的重構或功能改進。對於小專案而言,甚至可以簡化為:>.<次版本號>.<修訂版本號>。版本號比較自由,至於Beta版或者是正式版跟版本號之間並沒有任何關係,只要達到正式版的要求的話,即使版本號是1.0或者0.1都可能是正式版的。  

   * Alpha版: 此版本表示該軟體在此階段主要是以實現軟體功能為主,通常只在軟體開發者內部交流,一般而言,該版本軟體的Bug較多,需要繼續修改。  

   * Beta版: 該版本相對於α版已有了很大的改進,消除了嚴重的錯誤,但還是存在著一些缺陷,需要經過多次測試來進一步消除,此版本主要的修改對像是軟體的UI。  

   * RC版: 該版本已經相當成熟了,基本上不存在導致錯誤的BUG,與即將發行的正式版相差無幾。  

   * Release版: 該版本意味“最終版本”,在前面版本的一系列測試版之後,終歸會有一個正式版本,是最終交付使用者使用的一個版本。該版本有時也稱為標準版。一般情況下,Release不會以單詞形式出現在軟體封面上,取而代之的是符號(R)。 

2. 版本命名規範

   軟體版本號由四部分組成,第一個1為主版本號,第二個1為子版本號,第三個1為階段版本號,第四部分為日期版本號加希臘字母版本號,希臘字母版本號共有5種,分別為:base、alpha、beta、RC、release。例如:1.1.1.051021_beta。 

3. 版本號定修改規則

   * 主版本號:當功能模組有較大的變動,比如增加多個模組或者整體架構發生變化。此版本號由專案決定是否修改。 

   * 子版本號:當功能有一定的增加或變化,比如增加了對許可權控制、增加自定義檢視等功能。此版本號由專案決定是否修改。

   * 階段版本號一般是 Bug 修復或是一些小的變動,要經常釋出修訂版,時間間隔不限,修復一個嚴重的bug即可釋出一個修訂版。此版本號由專案經理決定是否修改。 

   * 日期版本號(051021):用於記錄修改專案的當前日期,每天對專案的修改都需要更改日期版本號。此版本號由開發人員決定是否修改。

   * 希臘字母版本號(beta):此版本號用於標註當前版本的軟體處於哪個開發階段,當軟體進入到另一個階段時需要修改此版本號。此版本號由專案決定是否修改。

語義化的版本控制 2.0.0-rc.1

在軟體管理世界裡存在著被稱作“依賴地獄”的死亡之谷,系統規模越大,引入的程式包越多,你就越有可能在不久的將來發現自己深陷絕望之中。

在多依賴的系統中釋出新版本程式包很快成為噩夢。如果依賴關係過緊密,可能面臨版本控制被鎖死的風險(必須對每一個依賴程式包改版才能完成某次升級)。而如果依賴關係過於鬆散,又無法避免版本混亂(\產生超過合理值的版本數/)。當你專案的進展由於版本控制被鎖死和/或版本混亂變得不那麼簡便和可靠,也就意味著你正處於依賴地獄之中。

為了解決這個問題,我提議通過一些規則和約束來表述版本號如何命名及何時更新。要使此係統正常運作,你首先需要宣告一個公共應用程式介面(以下簡稱API)。可以\以文件形式或程式碼形式實施/。需要注意的是,這個API必須是清晰和明確的。一旦公共API確定下來,你將通過版本號增量來描述版本修改。形如X.Y.Z(主版本號.副版本號.補丁號)這樣的版本格式。通過增加補丁號來表示不影響API的錯誤修復,增加副版本號來表示相容現有API的擴充套件/修改,而增加主版本號則表示不相容現有API的修改。

我稱這套系統為“語義化的版本控制”,在這套約定下,版本號及其更新方式 包含了相鄰版本間的\底層/程式碼和修改部分的資訊。

語義化版本控制說明(SemVer)

文件中出現的“必須”,“禁止”,“要求”,“應該”,“不該”,“可能”,“可能不”,“建議”,“也許”,和“可選”按RFC 2119規範解讀。

  1. 使用語義化版本控制的軟體必須 宣告公共API。該API可以在程式碼中宣告也可以固化為文件。無論何種形式,API\應該/是明確而全面的。

  2. 標準的版本號必須採用X.Y.Z的格式,其中X,Y,和Z為非負的整數。X是主版本號,Y是副版本號,而Z為補丁號。每個元素必須 取數值1為增量。例如:1.9.1->1.10.0->1.11.0。

  3. 標記版本號的軟體包釋出後,禁止改變該版本軟體包的內容。任何修改都必須以新版本釋出。

  4. 主版本號為0(0.y.z)的軟體處於開發初始階段,一切都可能隨時被改變。這樣的公共API不應該被視為穩定版。

  5. 1.0.0版本用於\界定/公共API的形成。這一版本之後所有的版本號更新都基於公共API及其修改。

  6. 補丁號Z(x.y.Z | x>0)必須增加,僅在相容原有介面的錯誤修復被引入時。錯誤修復指的是對不正確反應修復而進行的\內部修改/。

  7. 副版本號Y (x.Y.z | x>0)必須增加,如果新的、相容原有介面的功能被引入公共API;或者任何公共API被標記為棄用。副版本號可能增加,如果大量新功能或者改進被通過私有程式碼引入。這一過程中可能包含補丁級別的改變。當副版本號增加時補丁號必須置零。

  8. 主版本號X (X.y.z | X>0) 必須增加,如果任何不相容原有介面的改變被引入到公共API,這一過程中可能包含副版本級別和補丁級別的改變。當主版本號增加時補丁號和副版本號必須置零。

  9. 預釋出版本可以通過緊跟在補丁號後的一個破折號和一系列點號分隔的識別符號來修飾。這些識別符號必須由ASCII碼和破則號[0-9A-Za-z-]組成。預釋出版本\滿足需求/但優先順序低於相關聯的標準版本。例如: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92。

  10. 構建版本可以通過緊跟在補丁號或者預釋出本本號後的一個加號和一系列點號分隔的識別符號來修飾。這些識別符號必須由ASCII碼和破則號[0-9A-Za-z-]組成。構建版本\滿足需求/且優先順序高於相關聯的標準版本。例如:1.0.0+build, 1.3.7+build.11.e0f985a。

  11. 優先順序必須通過將版本號按主版本號,副版本號,補丁號,預釋出版本號,和構建版本號順序拆分後計算。主版本號,副版本號和補丁號以數值大小比較。預釋出和構建版本號必須通過如下方式將點號分隔的每一識別符號比較來確定:僅包含數字的識別符號以數值大小比較,含字母或破則號的以ASCII排序比較。數字識別符號的優先順序低於非數字識別符號。例如: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0-rc.1+build.1 < 1.0.0 < 1.0.0+0.3.7 < 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a 。

為什麼要使用語義化的版本控制?

這並不是一個新的或者革命性的主意。實際上,你可能已經在做一些近似的事情了。問題在於光“近似”還不夠。如果沒有一些正式的規範可循,版本號對於依賴管理並無實質意義。通過為這一主意命名並給予清晰的定義,讓你向軟體使用者傳達意向變得更為輕鬆。一旦這些意向變得清晰,靈活(而不過於靈活)依賴關係就能最終確定。

舉個例子來展示語義化的版本控制如何讓依賴地獄成為過去。假設有一個名為“救火車”的庫依賴另一個名為“梯子”的已納入語義版本控制的庫。救火車建立時,梯子的版本號為3.1.0。因為救火車呼叫的是3.1.0版本中的一些功能函式,你可以放心的指定梯子依賴為版本號大等於3.1.0而小於4.0.0。這樣,當梯子版本3.1.1和3.2.0釋出時,你就可以將直接它們納入你的程式包管理系統,因為它們能與原有依賴軟體相容。

作為一位負責任的開發者,你當然也會確保每個程序升級包的執行與表述一致。現實世界是複雜的,我們除了獨善其身外能做的不多。你所能做的就是讓語義化版本控制為你提供健全的程式包釋出和升級方式,而無需\重新整理程式包依賴/,節省時間減少煩惱。

如果你對此認同,希望立即開始使用語義化版本控制,你只需宣告正在使用它並遵循這些規則就可以了。請在你的README文件中保留此頁連結,讓別人也知道這些規則並重中受益。

FAQ

在0.y.z初始化開發階段,我該如何完成版本修訂?

最簡單的做法是以0.1.0作為你的初始化開發版本,在後續釋出中增加副版本號。

如何判斷髮布1.0.0版本的時機?

當你的軟體被用於生產環境,就很可能已經處於1.0.0階段了。如果使用者信賴你穩定的API,也應該釋出1.0.0版本。如果你為相容原有介面而擔心,你可能已經處於1.0.0階段了。

這不會阻礙快速開發和迭代?

主版本號為0完全為快速開發而存在。如果你每天都在改版API,那麼你不是處在0.x.x版本就是處在可能成為下一主版本的獨立分支的開發工作中。

如果對公共API的每個微小但不相容的改變都需要產生新的主版本呢 ,豈不會導致版本號很快達到42.0.0?

這實際上是開發者責任感和前瞻性的問題。不相容的改變不應該輕易被引入被大量依賴的程式碼中。升級所付出的代價可能是巨大的。不相容的改變將增加主版本號意味著你必須為這些改變帶來的影響深思熟慮,並評估相關的成本/受益率。

為全部公共API寫文件的工作量太大了!

為供他人使用的軟體編寫完整的文件這是你作為一名專業開發者應盡的職責,控制軟體複雜性是保持專案高 效的艱鉅而重要的部分。如果沒有人知道如何使用你的軟體或者不知道對某個方法的呼叫是是否可靠,這(控制軟體複雜性)將很難完成。而語義化版本控制,以及堅持對公共API的合理定義,可以保證每個人每件事執行順暢。

萬一不小心把一個不相容的改變作為副版本釋出了該怎麼辦?

一旦發現自己破壞了語義化版本控制規則,要儘快修復問題,併發佈一個糾正問題且相容原有介面的副版本。記住,修改一個已釋出版本的內容是不可接受的,即便在這種情況下。合適的情況下,將犯錯的版本寫入文件,告訴使用者問題所在,讓他們能夠意識到這是有問題的版本。

如果我更新了自己的依賴性卻沒有改變公共API該怎麼辦?

如果不影響公共API則認為此次更新是相容的。和你的程式包有相同依賴關係的軟體應該會有它自己的依賴關係說明,如有衝突軟體作者會在其中提出。此次改變是補丁級別還是副版本級別則取決於你更新依賴關係是想要修復bug還是引入新功能。後一種情況通常伴隨著附加程式碼,這顯然應該被判為副版本級別的更新。

如果正在修復的bug會產生與公共API不一致的程式碼該怎麼辦?(例如由於失誤導致程式碼與公共API文件不同步)

依靠你的判斷,如果你有一個大使用者會由於行為回滾到公共API文件而\徹底困擾/,那麼你可能應該進行一次主版本級別的更新,儘管這些修復從嚴格意義上來說是補丁級別釋出。記住,語義化的版本控制的全部精義在於通過版本號的變化來傳達意向。如果這些改變對於使用者來說是重要的,請通過變更版本號來通知他們。

如何處理即將棄用的功能?

棄用現存的功能是軟體開發中的家常便飯,也通常是向前發展所必須的。但當你棄用公共API的一部分時,你應該做兩件事:(1)更新文件以便使用者知道這個變化。(2)發行不包含棄用功能的副版本。在新主版本中完全移除棄用功能前,至少應有一個不包含棄用功能的副版本釋出,以便使用者能夠平滑過渡到新API。

關於

語義化的版本控制說明由Gravatars創辦者兼Github共同創辦者 Tom Preston-Werner 所著。