基于Maven和SVN的項(xiàng)目版本管理

流程demo.png

概述/背景

項(xiàng)目在開發(fā)過程中的版本盆犁,和在發(fā)布時(shí)的版本應(yīng)該有所區(qū)別戏蔑。發(fā)布的版本應(yīng)該保證一個(gè)版本號(hào)對(duì)應(yīng)唯一的內(nèi)容氧秘。

之前遇到過一個(gè)項(xiàng)目寻行,因?yàn)閜om中的版本號(hào)沒有-SNAPSHOT点晴,導(dǎo)致兩個(gè)環(huán)境依賴的項(xiàng)目雖然版本號(hào)相同感凤,其實(shí)不是同一個(gè)。當(dāng)時(shí)得出結(jié)論:相同的版本號(hào)只應(yīng)該對(duì)應(yīng)一個(gè)內(nèi)容粒督。

后來系統(tǒng)學(xué)習(xí)了下Maven陪竿,才具體了解到Maven體系中關(guān)于項(xiàng)目版本的標(biāo)準(zhǔn),這里分享出來,希望大家在維護(hù)項(xiàng)目版本的時(shí)候有據(jù)可依族跛。

另外闰挡,Maven中的版本管理需要結(jié)合軟件版本控制工具使用,如Git礁哄、SVN等长酗。雖然目前Git的使用已經(jīng)很普遍了,我的工作環(huán)境使用的是SVN桐绒,就以SVN為例進(jìn)行介紹夺脾。

Maven范圍的版本和SVN范圍的版本有不同的含義。前者面向的是項(xiàng)目茉继,代碼多次修改咧叭,項(xiàng)目的版本號(hào)可以不變;后者面向的是代碼烁竭,每一次修改都是一個(gè)不同的版本菲茬。下文所說的版本一般是指項(xiàng)目的版本,特殊情況下會(huì)說明是代碼版本颖变。

快照版本和發(fā)布版本

快照版本對(duì)應(yīng)開發(fā)過程中的版本生均,特點(diǎn)是快速的迭代更新,同樣的版本號(hào)對(duì)應(yīng)的是項(xiàng)目在一段時(shí)間內(nèi)的開發(fā)過程绿渣。

發(fā)布版本應(yīng)該是一個(gè)穩(wěn)定的版本须尚,它應(yīng)該對(duì)應(yīng)項(xiàng)目在某個(gè)時(shí)刻的狀態(tài) —— 它對(duì)應(yīng)唯一的代碼版本。

快照版本和發(fā)布版本.png

快照版本使用-SNAPSHOT后綴。

在Maven體系中的區(qū)別

Maven解析依賴的一般機(jī)制是:先從本地倉庫找泊脐,找不到再從遠(yuǎn)程倉庫找。換言之顶吮,在本地倉庫找到了父丰,就不會(huì)再去找遠(yuǎn)程倉庫。

如果有2個(gè)項(xiàng)目并行開發(fā)出牧,其中一個(gè)項(xiàng)目B依賴于另一個(gè)項(xiàng)目A穴肘。想象一下A和B都是持續(xù)更新的,項(xiàng)目B的開發(fā)人員如何確保能實(shí)時(shí)獲取項(xiàng)目A的最新內(nèi)容舔痕?

方案一:項(xiàng)目B的開發(fā)人員评抚,每次構(gòu)建之前都手動(dòng)從本地倉庫刪除項(xiàng)目A,這樣構(gòu)建的時(shí)候就會(huì)從遠(yuǎn)程倉庫下載最新的A伯复。

方案二:項(xiàng)目B的開發(fā)人員慨代,遷出項(xiàng)目A的代碼,自己將A項(xiàng)目安裝到本地倉庫啸如。

這兩個(gè)個(gè)方案都不是Maven體系推薦的做法侍匙,方案二讓項(xiàng)目B的開發(fā)人員不得不去搭建項(xiàng)目A的開發(fā)環(huán)境,而且項(xiàng)目A如果出現(xiàn)代碼問題叮雳,項(xiàng)目B的開發(fā)人員可能就無能為力了想暗。方案一增加了需要人工介入的工作量妇汗。

Maven使用SNAPSHOT來解決這個(gè)問題。如果項(xiàng)目依賴的是一個(gè)SNAPSHOT版本的依賴说莫,Maven會(huì)定期從遠(yuǎn)程倉庫獲取最新的內(nèi)容杨箭,默認(rèn)頻率是一天一次。也可以使用-U參數(shù)來強(qiáng)制更新唬滑。

所以告唆,項(xiàng)目A使用SNAPSHOT版本,項(xiàng)目B就可以定期或者實(shí)時(shí)獲取項(xiàng)目A的最新內(nèi)容晶密。

反之擒悬,如果項(xiàng)目A沒有使用SNAPSHOT,項(xiàng)目B在第一次從遠(yuǎn)程倉庫下載項(xiàng)目A到本地倉庫之后稻艰,就一直使用本地倉庫的這個(gè)備份懂牧。即使項(xiàng)目A更新了,項(xiàng)目B也不會(huì)知道尊勿,除非人工刪除了項(xiàng)目A在本地倉庫的副本僧凤。

所以,開發(fā)過程中的版本元扔,應(yīng)該使用SNAPSHOT版本躯保。

發(fā)布版本的版本號(hào)約定

一般的情況下是下面這種結(jié)構(gòu):

<主版本>.<次版本>.<增量版本> 比如 1.1.2

各版本的作用如下:

  • 主版本
    項(xiàng)目的重大架構(gòu)變更
  • 次版本
    較大范圍的功能變化
  • 增量版本
    大量或緊急bug修復(fù)

這只是一個(gè)粗略的劃分,大家可以根據(jù)自己的情況討論每一個(gè)版本的使用場(chǎng)景澎语。

通常主版本途事、次版本都會(huì)有,增量版本視情況而定擅羞。

更進(jìn)一步的情況尸变,可以添加里程碑版本,版本的結(jié)構(gòu)如下:

<主版本>.<次版本>.<增量版本>—<里程碑版本>3.1.2-alpha-1

里程碑版本表示達(dá)成項(xiàng)目的某個(gè)里程碑减俏,但通常不夠穩(wěn)定召烂。大部分的公司應(yīng)該不會(huì)使用里程碑版本,在此略過不表娃承。

版本維護(hù)流程

主干奏夫、標(biāo)簽和分支

  • 主干
    無需多說
  • 標(biāo)簽
    標(biāo)記某個(gè)有意義的代碼版本,每一個(gè)發(fā)布版本都應(yīng)該打一個(gè)標(biāo)簽草慧。
  • 分支
    用于并行開發(fā)桶蛔,通常用于已有版本的bug修復(fù)。

流程demo

流程demo.png
  1. 在主干進(jìn)行1.0.0-SNAPSHOT的開發(fā)漫谷,開發(fā)完成之后提交修改的代碼到主干仔雷。修改版本為1.0.0,再次提交,并添加標(biāo)簽碟婆。
  2. 隨后將版本改為1.1.0-SNAPSHOT电抚,提交。然后開始新一輪的開發(fā)竖共,完成之后提交代碼蝙叛,修改版本為1.1.0,再次提交并打標(biāo)簽公给。
  3. 接著將版本號(hào)改為1.2.0-SNAPSHOT借帘,提交,并開始新一輪的開發(fā)淌铐,在開發(fā)過程中1.1.0遇到一個(gè)緊急的bug肺然,新建分支并1.1.1-SNAPSHOT,修改版本號(hào)為1.1.1-SNAPSHOT腿准,提交并開始1.1.1-SNAPSHOT的開發(fā)际起。
  4. 1.1.1-SNAPSHOT開發(fā)完成,提交代碼吐葱。修改版本號(hào)至1.1.1街望,提交并打上標(biāo)簽。此時(shí)可以及時(shí)把1.1.1發(fā)布出去弟跑。同步分支到主干灾前。
  5. 隨后,1.2.0-SNAPSHOT開發(fā)完成..

版本號(hào)的修改應(yīng)該作為一次單獨(dú)的提交孟辑。在發(fā)布的時(shí)候豫柬,項(xiàng)目版本號(hào)初始為SNAPSHOT版本,提交完所有的代碼之后扑浸,修改版本號(hào)為發(fā)布版本,再提交燕偶;這次提交只修改版本號(hào)喝噪。
在開始新一輪的開發(fā)過程時(shí),修改版本號(hào)為新的SNAPSHOT指么,然后立即提交而不是修改代碼酝惧,版本號(hào)提交之后再開始開發(fā),這次提交只修改版本號(hào)伯诬。

SVN相關(guān)操作

SVN簡(jiǎn)單介紹

SVN是一個(gè)很簡(jiǎn)單的版本控制工具晚唇,你可以下載VisualSVN Server來搭建自己的SVN服務(wù)器。

SVNServer存儲(chǔ)結(jié)構(gòu).png

SVN的代碼主要是在倉庫里管理的盗似,如上圖demo就是一個(gè)倉庫哩陕。完整的倉庫目錄結(jié)構(gòu)如下:

倉庫目錄(Repositories)
  |-- 倉庫1
       |-- 項(xiàng)目1
            |-- 主干(trunk)
                 |-- 項(xiàng)目代碼
            |-- 標(biāo)簽?zāi)夸洠╰ags)
                 |-- 標(biāo)簽1
                      |-- 項(xiàng)目代碼
            |-- 分支(branches)
                 |-- 分支1
                      |-- 項(xiàng)目代碼

可以看到,SVN的每一個(gè)標(biāo)簽或者分支,都是一份完整的代碼副本悍及。

與倉庫同一個(gè)級(jí)別的是用戶等其他闽瓢,可以控制對(duì)倉庫的讀寫權(quán)限,具體沒有深入研究心赶,大家有需要自己研究下扣讼。

SVN操作

這里介紹上文版本維護(hù)流程中涉及到的操作。這里以命令的方式介紹缨叫,使用客戶端界面的自己找一下操作的位置椭符。

初始化項(xiàng)目

初始化項(xiàng)目首先要在VisulSVN Server的具體倉庫下新建一個(gè)項(xiàng)目結(jié)構(gòu):

倉庫-> 右鍵 -> 新建 –> Project Structure …

之后會(huì)生成一個(gè)標(biāo)準(zhǔn)的項(xiàng)目結(jié)構(gòu),包含了trunk耻姥、branches销钝、tags,沒有代碼咏闪。

獲取trunk的url地址曙搬,通過trunk -> 右鍵 -> Copy URL…

在本地項(xiàng)目所在目錄,輸入以下命令:

svn import -m "initial import" . https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk

添加標(biāo)簽

版本號(hào)修改為發(fā)布版本之后鸽嫂,應(yīng)該立即對(duì)當(dāng)前狀態(tài)添加一個(gè)標(biāo)簽:

svn copy https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/tags/1.0-RELEASE -m "tag 1.0-RELEASE"

創(chuàng)建分支

svn copy https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/tags/1.0-RELEASE https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches/1.0.1-SNAPSHOT -m "create branch 1.0.1-SNAPSHOT"

可以看到纵装,添加標(biāo)簽和創(chuàng)建分支本質(zhì)上都是復(fù)制。

切換分支

svn switch https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches/1.0.1-SNAPSHOT

合并分支

svn merge https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches/1.0.1-SNAPSHOT

合并分支的時(shí)候据某,pom文件中的版本號(hào)會(huì)有沖突橡娄。一般選擇使用當(dāng)前的版本號(hào)

Maven的release插件

在使用自動(dòng)化的插件之前癣籽,建議先手動(dòng)執(zhí)行上面的流程挽唉,熟悉版本維護(hù)的流程之后,再去使用自動(dòng)化插件筷狼。

配置pom文件

pom文件需要添加scm配置和插件配置瓶籽。scm是Software configuration management的縮寫。

<project>
    ...

    <scm>
        <connection>scm:svn:https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk</connection>
        <developerConnection>scm:svn:https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk</developerConnection>
        <url>https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/trunk</url>
    </scm>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-release-plugin</artifactId>
                <version>2.5.3</version>
                <configuration>
                    <tagBase>https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/tags</tagBase>
                    <branchBase>https://PC-LIJINLONG9.hikvision.com:444/svn/demo/demo-version/branches</branchBase>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

scm中配置了trunk的url埂材,connection和developerConnection的值都以scm開頭塑顺,之后跟著版本控制工具的類型svn。除了svn之外俏险,Maven還支持其他的工具严拒,如git。

插件里配置了標(biāo)簽的url和分支的url竖独,其實(shí)如果項(xiàng)目的結(jié)構(gòu)是標(biāo)準(zhǔn)的裤唠,trunk、tags和branches在同一級(jí)莹痢,可以不用配置這兩項(xiàng)种蘸。

配置完之后墓赴,就可以通過mvn命令來自動(dòng)發(fā)布、打標(biāo)簽劈彪、創(chuàng)建分支了竣蹦。

自動(dòng)發(fā)布

插件把發(fā)布分為2步,第1步執(zhí)行上文中版本維護(hù)流程中介紹的發(fā)布流程沧奴,第2步使用mvn deploy部署構(gòu)建至倉庫痘括。第1步由插件的prepare來完成,第2步由插件的perform目標(biāo)來完成滔吠。

如果prepare執(zhí)行失敗纲菌,可以通過rollback目標(biāo)來回滾,但是prepare生成的標(biāo)簽需要手動(dòng)刪除疮绷。

release:prepare

prepare負(fù)責(zé)預(yù)發(fā)布翰舌,在prepare之前,需要確保所有的修改都已經(jīng)提交了冬骚,而當(dāng)前的pom文件中的版本號(hào)還沒有升級(jí)為發(fā)布版本號(hào)椅贱。

prepare所做的工作有:

  1. 檢查系統(tǒng)是否有未提交的代碼
  2. 詢問用戶發(fā)布版本號(hào)、標(biāo)簽和下一個(gè)開發(fā)版本號(hào)只冻,并提供默認(rèn)值庇麦。
    What is the release version for "demo-version"? (com.hikvision.demo:demo-version) 1.2: :
    What is SCM release tag or label for "demo-version"? (com.hikvision.demo:demo-version) demo-version-1.2: :
    What is the new development version for "demo-version"? (com.hikvision.demo:demo-version) 1.3-SNAPSHOT: :
    
  3. 修改pom-根據(jù)用戶的輸入,將快照版本升級(jí)為發(fā)布版本
  4. 修改pom-根據(jù)用戶的輸入喜德,將scm中的地址改為標(biāo)簽對(duì)應(yīng)的地址
  5. 執(zhí)行Maven構(gòu)建
  6. 提交pom變更
  7. 根據(jù)用戶的輸入山橄,新建標(biāo)簽
  8. 修改pom-根據(jù)用戶的輸入將version升級(jí)為新的快照版本,將scm信息更新舍悯。
  9. 提交pom變更航棱。

上述的內(nèi)容,正是我們?cè)谏?jí)項(xiàng)目版本需要做的事情萌衬。

使用命令:mvn release:prepare饮醇。

release:rollback

回退release:prepare的所執(zhí)行的操作,并提交秕豫。但是歷史記錄會(huì)保留驳阎,創(chuàng)建的標(biāo)簽頁不會(huì)刪除。

使用命令:mvn release:rollback馁蒂。

release:perform

執(zhí)行版本發(fā)布。是基于發(fā)布版本標(biāo)簽地址所對(duì)應(yīng)的代碼進(jìn)行mvn deploy的結(jié)果蜘腌。

使用命令:mvn release:perform沫屡。

release:branch

自動(dòng)創(chuàng)建分支。

使用命令:

mvn release:branch -DbranchName=1.1.1 -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false

參考

  1. 《Maven實(shí)戰(zhàn)》 - 許曉斌
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撮珠,一起剝皮案震驚了整個(gè)濱河市沮脖,隨后出現(xiàn)的幾起案子金矛,更是在濱河造成了極大的恐慌,老刑警劉巖勺届,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驶俊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡免姿,警方通過查閱死者的電腦和手機(jī)饼酿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胚膊,“玉大人故俐,你說我怎么就攤上這事∥赏瘢” “怎么了药版?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)喻犁。 經(jīng)常有香客問我槽片,道長(zhǎng),這世上最難降的妖魔是什么肢础? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任还栓,我火速辦了婚禮,結(jié)果婚禮上乔妈,老公的妹妹穿的比我還像新娘蝙云。我一直安慰自己,他們只是感情好路召,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布勃刨。 她就那樣靜靜地躺著,像睡著了一般股淡。 火紅的嫁衣襯著肌膚如雪身隐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天唯灵,我揣著相機(jī)與錄音贾铝,去河邊找鬼。 笑死埠帕,一個(gè)胖子當(dāng)著我的面吹牛垢揩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播敛瓷,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼叁巨,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了呐籽?” 一聲冷哼從身側(cè)響起锋勺,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤蚀瘸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后庶橱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贮勃,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年苏章,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寂嘉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡布近,死狀恐怖垫释,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情撑瞧,我是刑警寧澤棵譬,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站预伺,受9級(jí)特大地震影響订咸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酬诀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一脏嚷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞒御,春花似錦父叙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蜻懦,卻和暖如春甜癞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宛乃。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工悠咱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人征炼。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓析既,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親谆奥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子渡贾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容