1. 程式人生 > >maven版本管理(十二)

maven版本管理(十二)

版本管理

一個健康的專案通常有一個長期的、合理的版本演變過程,如junit有3.7、3.8等版本,而有了版本的定義,那麼我們就可以針對版本做控制和管理。

那麼,版本管理和版本控制又是什麼,版本管理是指專案整體版本的演變過程管理,如從1.0到1.1-SNAPSHOT在到1.1,而版本控制是指藉助版本控制工具追蹤程式碼的每一個變更。這裡將要講述的是版本管理,但版本管理通常也是涉及到一些版本控制系統的操作及感念,請注意區分。

為了方便團隊的合作,在專案開發的過程中,大家都應該使用快照版本(SNAPSHOT),maven能夠很智慧的處理這種特殊的版本,解析專案各個模組的最新快照,快照版本機制促進團隊之間的內部交流,而當專案需要對外發布的時候,我們需要提供一個穩定的版本,使用該版本永遠只能夠定位到唯一的無變化的構件,而快照版本定位的構件可能隨時發生變化,對應的我們稱這種穩定的版本為釋出版本,當專案釋出了穩定版本之後,自然就進入了下一個開發週期,也就是一個新的快照版本。

版本管理關心的問題之一就是快照版本和釋出版本之間的轉換,快照版本對應了專案的開發過程,因此往往對應了很長時間,而正式版本對應了專案的釋出,因此僅僅代表某個時間專案的狀態。如圖

理想的釋出版本應該對應專案某個時刻的穩定狀態,這包括原始碼的狀態以及構建的狀態,因此這個時候專案的構建應該滿足一下條件:

1.所有自動化測試應該全部通過:如果有沒通過的測試,說明有問題需要修復,這是不穩定的、有問題的體現。

2.專案沒有依賴任何快照版本的依賴:快照版本的依賴,意味著不同時間點,構建的結果會有不同,會得到不同的構件,這會導致應用的不穩定或錯誤。

3.專案沒有配置任何快照版本的外掛:不同時間會引入不同的外掛快照,這回影響專案構建的穩定性。

4.專案所包含的程式碼已經全部提交到版本控制系統中:避免程式碼的丟失,專案某一個時刻狀態的丟失。

只有上述條件都滿足了,才可以修改專案的版本為釋出版本。

這裡我們應該合理的利用版本控制系統的標籤(Tag),正常使用中,專案所有的變化都記錄在主幹(Trunk)中,這樣我們找專案的某個時刻的狀態會比較麻煩,而使用標籤,我們就可以明確的把專案的某個時刻的狀態明確的標記出來,這裡說的是某個時刻的狀態,也就是專案的各個歷史釋出版本,這樣我們就可以很輕鬆的找到專案某個時刻的狀態,方便的進行比較,甚至是重新構建歷史版本的構件。

因此,將專案的快照版本更新為釋出版本後,應該在進行一次構建,以確保專案狀態是健康的,然後將這一變更提交到版本控制系統的主幹中,接著在為當前主幹的狀態打上標籤。

一個專案釋出版本的大致過程如下,當專案滿足更新為釋出版本的條件後,更改專案版本為釋出版本,做一次釋出版本的構建來確認專案的健康狀態,提交版本更新至主幹,為當前主幹打一個標籤(Tag),這就是一個釋出版本的過程。接下來就是更新發布版本至快照版本,進入下一個開發週期。

maven的版本號定義約定

例如:1.3.4-bate-2這個版本號,這往往表示了這個專案或產品的第一個重大版本的第三個次要版本的第四次增量版本的beta-2里程碑,也就是說maven的版本號定義約定是這樣的:<主版本>.<次版本>.<增量版本>-<里程碑版本> 。

主版本:表示了專案的重大架構變更,如maven1和maven2想去甚遠。

次版本:表示較大範圍的功能增加和變化,及bug修復。

增量版本:一般表示重大bug的修復,如1.4.0的bug修復後,版本為1.4.1。

里程碑版本:往往指某一版本的里程碑,如maven3已經發布了很多里程碑版本,如3.0-alpha-1、3.0-alpha-2,這樣的版本與正式的3.0相比,往往表示不是非常穩定,還需要很多測試。

注意:不是每個版本號都一定要包含這四個部分,一般宣告有主次兩個部分就可以,當新增依賴的時候,如果沒有宣告版本,那麼maven會根據版本號約定,自動解析最新版本,這個時候就需要對版本號進行排序,對於主、次、增量版本號是基於數字的比較好做出比較結果,而里程碑版本maven只會做簡單的字串比較,因此會有1.2-beta-3 > 1.2-beta-11這樣的結果,這需要特別留意。

主幹(trunk)、標籤(tag)與分支(branch)

主幹:專案開發程式碼的主體,是從專案開始到當前都處於活動的狀態,從這裡可以獲得專案最新的程式碼,以及幾乎所有的變更歷史。

分支:從主幹某個點分離出來的程式碼拷貝,通常可以在不影響主幹的情況下在這裡做重大bug的修復,或者做一些實驗性質的開發,如果達到預期的目的,就把變更合併到主幹中。

標籤:用來標識主幹或者分支的某個點的狀態,以代表專案的某個穩定狀態,這通常就是版本釋出時的狀態。

使用maven管理版本的時候,也涉及了很多版本控制系統的操作,如圖:

圖中展示的是一個典型的專案版本變化過程,專案從1.0.0-SNAPSHOT快照版本進行開發,1.0.0釋出並打一個標籤,然後進入1.1.0-SNAPSHOT快照版本開發,1.1.0版本釋出,1.1.0打一個標籤,進入1.2.0-SNAPSHOT快照版本開發,這個時候,發現1.1.0版本有個重大的bug,但是主幹1.2.0-SNAPSHOT已經有了很多變化,這這個主幹上修復bug是不利於快速測試修復的驗證的,所以我們在1.1.0的標籤上拉取一個分支1.1.1-SNAPSHOT快照版本,並在這個分支上做bug修復和測試驗證,當驗證通過,釋出1.1.1版本,並打一個標籤,同時把修復所做的改動合併到主幹1.2.0-SNAPSHOT上,然後1.2.0釋出並打標籤,進入1.3.0的開發階段,這裡涉及了快照版本和釋出版本的切換,maven版本號約定的應用,以及版本控制系統主幹、標籤和分支的使用,這其實也是一個不成文的行業標準,理解這個過程之後,不僅可以更方便的學習開源專案,也能對專案的版本管理更加的標準和清晰。

自動化版本釋出

使用maven-release-plugin外掛,自動完成版本釋出所做的操作,只要提供一些必要的資訊,該外掛主要有三個目標,如下:

release : prepare   準備版本釋出,依次執行下列操作:

檢查專案是否有未提交的程式碼

檢查專案是否有快照版本的依賴

根據使用者的輸入將快照版本升級為釋出版本

想pom中的scm資訊更新為標籤地址

基於修改後的pom執行maven構建

提交pom

基於使用者輸入為程式碼打標籤

將程式碼從釋出版升級為新的快照版

提交pom變更

release : rollback 回退 release : prepare 所執行的操作,將pom回退至 release : prepare之前的狀態,並提交。需要注意的是,該動作不會刪除 release : prepare生成的標籤,所以需要使用者手動刪除。

release : perform 執行版本釋出。簽出release : prepare生成的標籤中的原始碼,並在次基礎上mvn deploy命令,打包並部署構件至倉庫。

要為專案釋出版本,首先需要為其新增正確的版本控制系統資訊,這是因為maven-release-plugin外掛需要知道版本控制系統的主幹、標籤等地址資訊後才能執行相關的操作。

一般配置專案scm資訊如下:

<!--原始碼倉庫資訊-->
<scm>
<!--只讀的scm地址-->
<connection>scm:git:https://github.com/123456/test-parent.git</connection>
<!--可寫的scm地址-->
<developerConnection>scm:git:https://github.com/123456/test-parent.git</developerConnection>
<!--可以在瀏覽器訪問的scm地址-->
<url>https://github.com/123456/test-parent.git</url></scm>

這裡的配置只是告訴maven當前專案的倉庫位置,而版本控制還需要涉及標籤操作。配置如下:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.5.3</version>
    <configuration>
 <username>username</username>
  <password>password</password>
tag地址,標籤的基礎目錄
 <tagBase>https://github.com/123456/test-parent.git</tagBase> </configuration> </plugin></plugins>

在執行mvn release:prepare之前,要確保兩點:

1.系統必須提供scm版本控制軟體的命令列工具,maven需要命令列工具執行相應的操作。

2.pom必須配置了可用的部署倉庫,因為mvn release:perform會簽出標籤的程式碼,執行deploy操作將構件釋出到倉庫中。

另外,mvn release:prepare -DautoVersionSubmodules=true 這個帶引數的命令的作用是,當我們管理聚合專案的時候,忽略個模組的版本確認,使各個模組都使用與父模組一致的版本。

在版本管理的過程中,生成的配置檔案,我們不需要動,當我們執行perform命令之後,會自動消失。

在maven構建的過程中,一些功能我們並沒有進行配置,但是確自動生效了,這是因為我們繼承了超級pom中的配置,perfile配置的屬性,會在條件達成的時候被啟用使用,而我們使用版本管理外掛的時候,該外掛激活了某些配置,所以才有這個效果。具體超級pom配置請看maven的超級pom檔案。

自動化建立分支

使用maven-release-plugin外掛的branch目標可以幫我們實現自動建立分支,他會做這些操作:

檢查本地有無未提交的程式碼

為分支更改pom的版本,例如從1.1.0-SNAPSHOT改為1.1.1-SNAPSHOT

將POM中的scm資訊更新為分支地址

提交以上更改

將主幹的程式碼複製到分支中

修改原生代碼,使其回退到修改之前的版本(使用者可以指定新的版本)

提交本地更改

當然,我們還需要配置分支的目錄地址,

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.5.3</version>
    <configuration>
      <username>sunhongwu</username>
      <password>shwsunhongwu5</password>
<!--標籤-->
<tagBase>https://github.com/123456/test-parent.git</tagBase>
<!--分支-->
<branchBase>https://github.com/123456/test-parent.git</branchBase>
    </configuration>
  </plugin>
</plugins>

mvn release:branch 生成分支

-DbranchName=test-parent-beta-1 設定分支的目錄名

-DupdateBranchVersions=true  設定分支使用新的版本

-DupdateWorkingCopyVersions=false 不更新(原生代碼)主幹版本

-DautoVersionSubmodules=true  多模組和父模組使用相同的版本

GPG簽名

當我們獲取一個構件的時候,我們希望可以校驗這個構件是否是我們指定的組織釋出的構件,並且校驗是否被篡改,我們自己帆布的構件,可能使用著也希望可以做這樣的校驗。

PGP(pretty good privacy)就是這樣一個幫助提高安全性的技術,pgp最長用來給電子郵件進行加密、解密以及提供簽名,以提高電子郵件交流的安全性,這裡介紹下如何使用pgp技術為我們釋出的構件簽名,為專案增強安全性。

GnuPG簡稱GPG,是PGP標準的一個免費實現,無論是類unix平臺還是windows平臺都能使用,GPG能夠幫助我們為檔案生成簽名、管理金鑰,以及驗證簽名等。

maven-gpg-plugin外掛可以幫助我們自動做這個工作,避免複雜無聊的手工操作,簽名、部署到倉庫自動完成,此處暫不做說明,日常使用中,很少需要簽名,而且使用外掛也需要在相應的平臺安裝gpg的分發包。