我有一个Web应用程序,我们可以在功能准备就绪时部署到 生产环境 环境,有时可能每天运行几次,有时可能需要几周时间才能发布 .
目前,我们不会为我们的项目增加我们的版本号,并且所有内容都在版本 0.0.1-SNAPSHOT
上持续了一年多 . 我想知道为Web应用程序进行持续交付的Maven方式是什么 . 在每次提交时提高版本号并且从不像我们现在所做的那样碰撞版本号似乎有点过分,似乎也是错误的 .
What is the recommend best practice for this type of Maven usage?
问题实际上是双重问题:
-
在单个
pom.xml
文件中推进项目版本号(可以有很多) . -
更新所有相关组件中的版本号,以使用彼此的最新版本号 .
7 回答
我推荐以下演示文稿,讨论使用Maven进行持续交付的实际情况:
You tube presentation on CD with Maven
Slides
关键点是每个构建都是一个潜在的版本,所以不要使用快照 .
这是我根据Mark O'Connor的回答链接的视频摘要 .
该解决方案需要像git这样的DVCS和像Jenkins这样的CI服务器 .
Don 't use snapshot builds in the Continuous Delivery pipeline and don' t使用maven发布插件 .
1.0-SNAPSHOT
等快照版本将转换为实际版本,例如1.0.buildNumber
,其中buildNumber
是Jenkins作业编号 .算法步骤:
Jenkins使用源代码克隆git repo,并说源代码版本为
1.0-SNAPSHOT
Jenkins创建了一个名为
1.0.JENKINS-JOB-NUMBER
的git分支,因此快照版本变成了真实版本1.0.124
Jenkins调用maven版本插件将pom.xml文件中的版本号从
1.0-SNAPSHOT
更改为1.0.JENKINS-JOB-NUMBER
詹金斯调用
mvn install
如果
mvn install
成功,那么Jenkins将提交分支1.0.JENKINS-JOB-NUMBER
,并且在git中使用适当的标记创建真正的非快照版本以便稍后再现 . 如果mvn install
失败,那么Jenkins将删除新创建的分支并使构建失败 .我强烈推荐Mark的答案链接的视频 .
从Maven 3.2.1开始,支持开箱即用的交付友好版本:https://issues.apache.org/jira/browse/MNG-5576您可以在版本中使用3个预定义变量:
所以你基本上做的是:
将您的版本设置为例如
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来生成有趣的构建号 .
一旦发现构建稳定(例如通过验收测试),您就可以将版本推送到Nexus或其他存储库 . 任何不稳定的构建都会变成垃圾 .
有一些很好的讨论和建议如何处理maven版本号和持续交付(CD)(我将在我的部分答案之后添加它们) .
首先我对SNAPSHOT版本的看法 . 在maven中,SNAPSHOT显示当前正在开发到SNAPSHOT后缀之前的特定版本 . 因此,像Nexus或maven-release-plugin这样的工具对SNAPSHOTS有特殊的处理方式 . 对于Nexus,它们存储在一个单独的存储库中,并允许使用相同的SNAPSHOT版本更新多个人工制品 . 所以SNAPSHOT可以在你不知道的情况下改变(因为你永远不会增加你的pom中的任何数字) . 因此,我不建议在项目中使用SNAPSHOT依赖项,特别是在CD世界中,因为构建不再可靠 .
由于上述原因,当您的项目被其他项目使用时,SNAPSHOT作为项目版本将是一个问题 .
对我来说,SNAPSHOT的另一个问题是不再可追溯或可重复 . 当我在 生产环境 中看到版本0.0.1-SNAPSHOT时,我需要进行一些搜索以找出它是从构建的修订版本构建的 . 当我在文件系统上找到该软件的版本时,我需要查看pom.properties或MANIFEST文件,看看这是旧垃圾还是最新最好的版本 .
为了避免手动更改版本号(特别是当您每天构建多个版本时),让构建服务器为您更改编号 . 所以为了发展,我会选择
版本,但在构建新版本时,构建服务器可以用更独特和可追踪的东西替换SNAPSHOT .
例如其中一个:
因此,主要和次要数字可用于营销问题或仅显示达到新的重要里程碑,并且可以在您需要时手动更改 . buildNumber(来自Continuous Integration服务器的编号)或scmNumber(SUbversion或GIT的修订版)使每个版本都是唯一且可追踪的 . 使用buildNumber或Subversion修订时,项目版本甚至可以排序(不使用GIT编号) . 使用buildNumber或scmNumber也很容易看出此版本中有哪些更改 .
另一个例子是使用的stackoverflow的版本控制
这里缺少链接:
Versioning in a Pipeline
Continuous Delivery and Maven
DON'T DO THIS!
因为Maven在连字符之后将任何东西视为LEXICAL,所以会在背后咬你 . 这意味着版本1将在词法上高于10 .
这很糟糕,好像你在maven中要求最新版本的东西,然后上述点获胜 .
解决方案是使用小数点而不是构建号之前的连字符 .
DO THIS!
在本地拥有SNAPSHOT版本是可以的,但作为构建的一部分,最好使用它
有一些方法可以从pom派生主要/次要版本,例如使用help:在调用版本之前评估和管道到环境变量:set . 这很脏,但我真的摸不着头脑(以及我团队中的其他人)让它更简单,而且(当时)Maven还不够成熟,无法处理这个问题 . 我相信Maven 2.3.1可能会有一些帮助这个的东西,所以这些信息可能不再相关 .
对于一群开发人员来说,在同一个major.minor版本上发布是可以的 - 但是要注意微小的更改是非破坏性的,并且主要的版本更改会导致一些重大的API更改或功能/行为的弃用 .
从持续交付的角度来看,每个构建都可能是可释放的,因此每次签入都应该创建一个构建 .
作为起点,你可以看看Maven: The Complete Reference. Project Versions.
然后有一个很好的post on versioning strategy.
在我的网络应用程序工作中,我们目前使用此版本控制模式:
<jenkins build num>-<git-short-hash>
示例:247-262e37b9 .
这很好,因为它为您提供了一个始终唯一且可追溯到jenkins构建版本和生成它的git版本的版本 .
在Maven 3.2.1中,他们最终杀死了使用$ 作为版本的警告,这样就可以很容易地构建它们 . 只需更改所有poms即可使用
<version>${revision}</version>
并使用-Drevision=whatever
进行构建 . 唯一的问题是,在你发布的poms中,版本将保留在实际pom文件中的${revision}
,这可能会导致各种奇怪的问题 . 为了解决这个问题,我写了一个简单的maven插件(https://github.com/jeffskj/cd-versions-maven-plugin),它在文件中进行变量替换 .