自动项目版本在连续交付时的Maven方式是什么?
我有一个Web应用程序,当某个function准备就绪时,我们可以将其部署到生产环境中,有时可能是一天几次,有时也可能是几个星期之间发布。
目前,我们并没有为我们的项目增加版本号,一切都已经在0.0.1-SNAPSHOT
一年多了。 我想知道什么是做一个networking应用程序连续交付的Maven方式。 在每次提交时碰到版本号似乎过火,而且从未像现在这样冲突版本号似乎也是错误的。
这种types的Maven使用推荐的最佳做法是什么?
问题实际上是双重的:
- 推进个人
pom.xml
文件中的项目版本号(可以有很多)。 - 更新所有相关组件中的版本号以使用最新的相关组件。
我推荐以下介绍,讨论使用Maven进行连续交付的实际情况:
- 你用Maven在CD上进行pipe理演示
- 幻灯片
关键是每个构build都是一个潜在的版本,所以使用Maven版本插件,不要使用快照。
这是我根据Mark O'Connor的回答链接的video的总结。
- 这个解决scheme需要一个DVCS,比如git和一个像Jenkins这样的CI服务器。
- 不要在Continuous Deliverypipe道中使用快照构build,也不要使用maven release插件。
- 快照版本(如
1.0-SNAPSHOT
转换为真正的版本,如1.0.buildNumber
,其中buildNumber
是Jenkins作业编号。
algorithm步骤:
- Jenkins使用源代码克隆git repo,并说源代码版本为
1.0-SNAPSHOT
- Jenkins创build了一个名为
1.0.JENKINS-JOB-NUMBER
的git分支,以便将快照版本转换为真正的版本1.0.124
- Jenkins调用Maven版本插件,将pom.xml文件中的版本号从
1.0-SNAPSHOT
更改为1.0.JENKINS-JOB-NUMBER
- jenkins调用
mvn install
- 如果
mvn install
成功,那么Jenkins将提交分支1.0.JENKINS-JOB-NUMBER
并在git中使用适当的标记创build一个真正的非快照版本,以便稍后重现。 如果mvn install
失败,那么Jenkins将只删除新创build的分支,并使构build失败。
我强烈推荐Mark的答案。
关于如何处理maven版本号和连续发送(CD)有一些很好的讨论和build议(我将在我的答案部分之后添加它们)。
所以首先我对SNAPSHOT版本的看法。 在maven中,SNAPSHOT显示目前正在开发到SNAPSHOT后缀之前的特定版本。 正因为如此,像Nexus或maven-release-plugin这样的工具对SNAPSHOTS有着特殊的处理。 对于Nexus,它们存储在单独的存储库中,并允许使用相同的SNAPSHOT发行版来更新多个文物。 所以一个SNAPSHOT可以在你不知道的情况下改变(因为你永远不会增加你的任何数量)。 因此,我不build议在项目中使用SNAPSHOT依赖项,特别是在CD世界中,因为构build不再可靠。
SNAPSHOT作为项目版本将是一个问题,当您的项目被其他人使用时,由于上述原因。
对我来说,SNAPSHOT的另一个问题是,它不再是真正的可追踪或可重复的。 当我在生产中看到一个版本为0.0.1-SNAPSHOT时,我需要进行一些search,以确定它是从哪个版本开始构build的。 当我在文件系统上find这个软件的版本时,我需要查看pom.properties或者MANIFEST文件,看看这是旧的垃圾还是最新最好的版本。
为了避免手动更改版本号(特别是当您每天构build多个版本时),请让Build Server更改您的编号。 所以为了发展,我会去一个
<major>.<minor>-SNAPSHOT
版本,但是当构build新版本时,构build服务器可以用更独特和可追踪的东西replaceSNAPSHOT。
比如其中之一:
<major>.<minor>-b<buildNumber> <major>.<minor>-r<scmNumber>
因此,主要和次要的数字可以用于市场营销问题,或只是表明,一个新的伟大的里程碑已经达成,可以手动改变任何你想要的。 buildNumber(来自您的持续集成服务器的编号)或scmNumber(SUbversion或GIT的修订版)使每个版本都具有唯一性和可追溯性。 当使用buildNumber或Subversion版本时,项目版本甚至可以sorting(不包括GIT编号)。 使用buildNumber或scmNumber也很容易看到在这个版本中有什么变化。
另一个例子是使用的stackoverflow版本
<year>.<month>.<day>.<buildNumber>
在这里,缺less的链接:
- pipe道中的版本控制
- 持续交付和Maven
从Maven开始3.2.1持续交付友好版本开箱即用: https : //issues.apache.org/jira/browse/MNG-5576您可以在版本中使用3个预定义的variables:
${changelist} ${revision} ${sha1}
所以你基本上做的是:
- 将您的版本设置为例如
1.0.0-${revision}
。 (您可以使用mvn versions:set
在多模块项目中快速正确地执行此操作。) - 为本地开发添加一个属性
<revision>SNAPSHOT</revision>
。 - 在您的CI环境中运行
mvn clean install -Drevision=${BUILD_NUMBER}
或者类似的东西,甚至是mvn clean verify -Drevision=${BUILD_NUMBER}
。
您可以使用例如https://wiki.jenkins-ci.org/display/JENKINS/Version+Number+Plugin来生成有趣的内部版本号。;
一旦你发现构build是稳定的(例如通过验收testing),你可以将版本推送到Nexus或其他存储库。 任何不稳定的构build只是去垃圾。
不要这样做!
<Major>.<minor>-<build>
会咬你的背后,因为Maven将连字符后的任何东西都视为LEXICAL。 这意味着版本1将在词汇上高于10。
这很糟糕,就像你要求maven中最新版本的东西一样,那么上面的点就会胜出。
解决scheme是使用小数点而不是在构build号之前的连字符。
做这个!
<Major>.<minor>.<build>
可以在本地使用SNAPSHOT版本,但作为版本的一部分,最好使用
mvn versions:set -DnewVersion=${major}.${minor}.${build.number}
有一些方法可以从pom中派生主要/次要版本,例如使用help:在调用版本:set之前评估和pipe道到环境variables。 这很肮脏,但是我真的抓住了我的头(和我的团队中的其他人),使得它更简单,而且(当时)Maven还不够成熟,无法处理这个问题。 我相信Maven 2.3.1可能有一些帮助这个方法的东西,所以这个信息可能不再相关。
一群开发人员可以在同一个major.minor版本上发布是可以的 – 但是要注意小的变化是不会中断的,而主要的版本变化会有一些突变的API变更,或者function/行为的弃用。
从持续交付的angular度来看,每个构build都可能是可释放的,因此每个签入应该创build一个构build。
作为一个起点,你可以看看Maven:完整的参考。 项目版本。
然后在版本控制策略上有一个很好的post。
在我的networking应用工作中,我们目前使用这种版本模式:
<jenkins build num>-<git-short-hash>
例如:247-262e37b9。
这很好,因为它给了你一个始终独特的版本,并且可以追溯到生成它的jenkins构build和git修订版本。
在Maven 3.2.1+中,他们终于杀死了使用$ {property}作为一个版本的警告,这样可以很容易地构build这些警告。 只需要将所有的poms改为使用<version>${revision}</version>
然后使用-Drevision=whatever
构build-Drevision=whatever
。 唯一的问题是,在你的发布版本中,版本将停留在实际的pom文件中${revision}
,这会导致各种奇怪的问题。 为了解决这个问题,我写了一个简单的maven插件( https://github.com/jeffskj/cd-versions-maven-plugin ),在文件中进行variablesreplace。