版本的故事(五)闖關旅程
對於程式碼的任何一次修改都會形成一個「版本」,其中的大部分版本是沒有必要發布的,它們只是普通的提交。當開發人員完成一個里程碑計劃,就在這個提交上創建一個基準線(具體操作在 Git 平台上創建一個 Tag),標記這個特殊的提交,形成一個正式的「版本」。
一些研發團隊使用「持續集成」開發過程,對每一個提交,都編譯一個二進位包,將這二進位包部署在集成環境里,頻繁進行集成測試,提高品質和工作效率。對於這些頻繁的提交,不必為每一個二進位包編一個正式的版本號,我們可以用「SNAPSHOT」後綴標識這些頻繁集成的版本。「SNAPSHOT」版本也稱作「開發版」,例如:「1.2.3-SNAPSHOT」就是「正在開發中的1.2.3版本」。連續多個版本的名稱都是相同的,這樣就不必頻繁改動部署腳本,可以加快集成部署的頻率。
SNAPSHOT版本是不能作為正式版本發布給用戶的,因為它們是「不穩定」的。「不穩定」的一個含義是這些版本還在開發中,沒有經過測試驗證,品質不穩定;另一個含義是其二進位包是不穩定狀態,隨時可能會被下一次提交覆蓋。如果這樣的版本發布出去,就會形成無法回溯的版本,給維護帶來麻煩。
開發人員創建Tag,編譯一個二進位包,提交給測試人員進行測試,這個版本稱之為「候選發布版本」(Release candidate,簡稱 RC)。從現在開始,二進位包進入了一個「闖關旅程」。闖關成功才能成為真正的「Release」版本。
對於程式碼的任何一次修改都有被發布出去的可能性。開發人員問自己:「我們這次修改的版本是否應該發布出去?」,得到的答案只是一次臆測的結果。後續的一系列過程:構建、部署、測試流程能夠驗證是否可以發布這個版本,不斷讓我們增強信心。儘管每次修改都可以產生一個能夠交給用戶的最終產物,但是我們應該首先對每次修改都進行適用性評估。只有這次修改沒有缺陷,並且滿足由客戶定義的驗收條件,才能夠發布它。——以上內容摘錄自《持續交付:發布可靠軟體的系統方法》
Snapshot——Release candidate——Release,這就是一個發布包的「闖關旅程」,能不能過關,取決於研發人員和測試人員的驗證結果。
有一些團隊制定了版本號命名規範,為發布候選版和發布版添加不同的後綴,比如「2.0.5.RC」、「2.0.5.RELEASE」,這樣用戶可以從版本號上判斷它的品質等級。然而這也不是絕對準確的,因為即使是發布版,也有可能隨時發現一個缺陷,成為一個廢棄版本。所以一種普遍的做法是:只在快照版上使用「SNAPSHOT」後綴,發布候選版和發布版沒有後綴,用戶需要關注軟體的發布說明,確定某個版本的品質水平。
安裝包如何保存?放進版本庫里通常不是明智之舉。版本庫通過增量存儲來減少存儲所消耗的磁碟空間,但是這通常是對文本文件有效。對於文本文件,比如源程式碼文件,只記錄文件的那幾行更改了,而非整個新版本,以此來減少存儲消耗的磁碟空間。對於二進位的安裝包,這個辦法則難以實現。而另一方面,對於安裝包,很多歷史版本,比如送去測試用的安裝包,是不值得長期保存的,需要定期清理,否則會佔用大量的磁碟空間。版本庫原則上保存全部歷史版本,如果要刪除已經沒用的歷史版本,會很麻煩。不像在平常的文件系統上。因此,用版本庫來存儲安裝包,反而帶來不便。——以上內容摘錄自《理解軟體配置管理》
在很多企業內部,採用一些專門的二進位包管理的工具。研發人員提交程式碼,自動打包,上傳到二進位包管理平台,自動部署工具從平台上下載二進位包,部署到測試環境上——這就是持續集成、持續交付的過程。有很多非常好的開源二進位包管理平台,以下是其中非常著名Nexus:
Nexus 是一個強大的二進位包管理平台,支援幾乎所有的技術路線,比如Maven、NPM、RPM、Docker 等等,還支援原始二進位包。關於二進位包管理平台的使用,有兩點需要注意:
1:對於公司正在使用的第三方系統的安裝包,比如MySQL、MongoDB、各種開發庫,應該把它們的二進位包保存到內部的二進位包管理平台上。這樣不僅可以規範管理所有的版本,避免開發人員使用一些來源不明的軟體,還能加快下載速度,節約時間。
2:對於自研的模組,應該建立多個倉庫,把不同品質等級的二進位包分別保存到不同的倉庫。研發人員提交程式碼,編譯產物上傳到快照庫;完成里程碑任務,生成發布候選版本,上傳到發布候選庫;測試合格的版本上傳到發布庫。這樣可以對不同的倉庫採用不同的管理策略,比如定期清理快照庫,發布候選版本保留3年,發布版倉庫採用最高級別的存儲設備,確保永久保存。