Maven 分支更新项目版本自动化发布工作流程
我有一个关于 Maven 自动化项目版本控制的困难案例需要解决,我希望我能根据您的经验和建议找到合适的解决方案。
问题是这样的: 我们有一个巨大的 mavenized java 产品,其中包含约 200 个非常相互依赖的不同项目。 我们同意每个项目都应该独立开发,这样每个项目都应该有自己的生命周期。 开发阶段一切正常,没有问题。当我们为这些项目准备发布时,问题就来了:因为项目太多,手动更改很痛苦,所以我们决定找到一个自动化的解决方案来解决发布过程。
前提条件是: 我们一致认为,从 SVN 角度来看,发布策略应该是这样的: - 所有开发都应在 SVN 主干上进行,版本应在分支上创建和维护。每个执行的发布都应该自动创建一个标签。
从MAVEN角度来看,策略是这样的: - 在发布项目之前,我们首先将主干复制到分支,以便控制分支代码上的项目维护。我们选择的版本控制系统是:Major.Minor.BuildNumber-SNAPSHOT(例如1.0.0-SNAPSHOT)。当分支代码时,我们希望通过增加MinorVersion来更改项目版本号(例如trunk-1.0.0-SNAPSHOT将变为1.1.0-SNAPSHOT,而1.0.0-SNAPSHOT将在新创建的分支上复制并发布) - 当我们确定项目足够成熟以便发布时,我们将使用maven-release-plugin来发布它(mvn release:clean release:prepare release:perform)这样我们的项目版本就会从Major.Minor.BuildVersion-SNAPSHOT(例如1.0.0-SNAPSHOT)转换为Major.Minor.BuildVersion(例如1.0.0),然后将为下一次开发迭代做好准备,例如:Major.Minor.BuildVersion+1-SNAPSHOT (eg 1.0.1-SNAPSHOT)
我们面临的问题是与项目版本控制相关。 因此,在主干上的开发阶段,所有项目都使用其依赖项的最新 SNAPSHOT 版本 (mvn versions:use-latest-versions -DallowSnapshots=true -DupdateDependency=true),但是当我们认为是时候开始发布程序并准备分支代码了,但出现了问题: 我们开始分支
parent-pom
(mvn -Brelease:cleanrelease:branch -DbranchName=${project.artifactId}_${project.version} -Dusername=${username} -Dpassword=${passwd} -Dproject.rel .${groupId}:${projectId}=1.0.0-SNAPSHOT -Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT)
- 将项目从主干复制到新创建的分支,将主干上的pom版本从1.0.0-SNAPSHOT转换为1.1.0-SNAPSHOT
非依赖项目
(mvn -Brelease:cleanrelease:branch -DbranchName=${project.artifactId}_${project.version} -Dusername=${username} -Dpassword=${passwd} -Dproject.rel .${groupId}:${projectId}=1.0.0-SNAPSHOT -Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT 版本:update-parent -DallowSnapshots=true)
- 将项目从主干复制到新创建的分支,
- 将 trunk pom 版本 1.0.0-SNAPSHOT 转换为 1.0.1-SNAPSHOT
- 更新parent-pom.version:1.0.0-SNAPSHOT 变为 1.1.0-SNAPSHOT
依赖项目:
(mvn -Brelease:cleanrelease:branch -DbranchName=${project.artifactId}_${project.version} -Dusername=${username} -Dpassword=${passwd} -Dproject.rel .${groupId}:${projectId}=1.0.0-SNAPSHOT -Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT 版本:update-parent -DallowSnapshots=true 版本:使用最新版本 -DallowSnapshots=true -DupdateDependency=true)
- 将项目从主干复制到新创建的分支
- 将 trunk 上的 pom 版本从 1.0.0-SNAPSHOT 转换为 1.1.0-SNAPSHOT
- 将主干上的parent-pom从1.0.0-SNAPSHOT更新为1.1.0-SNAPSHOT
- 将已分支的依赖项项目从 1.0.0-SNAPSHOT 更新为 1.1.0-SNAPSHOT
这里的第一个问题是目前还没有办法在分支项目时增加 MinorVersion 的参数,maven-release-plugin 2.2.2 在分支时不会增加 trunk 上的 pom MinorVersion,所以这就是为什么我们需要使用 -Dproject .rel.${groupId}:${projectId}=1.0.0-SNAPSHOT -Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT 参数并为每个项目手动更改它们,因此每次我们准备新版本时都会更改 200 次。
我想知道这是否不是一种以自动化方式完成所有描述的过程并且不需要一直手动执行所有这些更改的方法。 我们甚至考虑模块化这个产品,以便将这 200 个项目折叠成 100 个,但这是不可接受的,因为我们的想法是要有一个细粒度的项目版本控制,并使所有项目都有自己的生命周期,所以需要一个聚合器(我的意思是经典的)这里不予讨论。
我们使用 SVN 作为 VCS,使用 Maven 作为构建工具(可能你已经明白了:)),使用 Bamboo 作为 CI 服务器(实际上,Bamboo 并没有提供“Maven 依赖处理器”功能),在版本控制问题)。
你们有什么想法可以找到这个问题的正确解决方案,也许另一个插件会有所帮助(versions-maven-plugin 在分支时不会自动更改版本),也许对此有另一种观点,我不知道知道...,欢迎任何帮助或建议。
谢谢!
I have a difficult case to solve regarding the Maven automated projects versioning, I hope I'll find a proper solution based on your experience and advices.
The problem is like that:
We have a huge mavenized java product which comprise of ~200 very interdependent different projects.
We agreed that each project should be developed independently, so that each of them should have it's own lifecycle.
It's all working fine in the development stage, there is no problem. The problem comes when we are preparing the release for these projects: Because the are so many projects the manual changes are a pain so we decided to find an automated solution to solve the release process.
The prequisites are these:
We all agreed that the release policy from SVN perspective should be like that:
- all development should be performed on SVN trunk, releases should be created and maintained on branches. Each performed release should automatically create a tag.
The policy from MAVEN perspective is like that:
- before releasing a project, we first copy the trunk to a branch in order to have control over projects maintainance on the branched code. The versioning system we choose is: Major.Minor.BuildNumber-SNAPSHOT (e.g. 1.0.0-SNAPSHOT). When branching the code, we want to change the project version number by incrementing the MinorVersion (e.g trunk-1.0.0-SNAPSHOT will become 1.1.0-SNAPSHOT, and 1.0.0-SNAPSHOT will be copied and released on the new created branch)
- when we decide that the project is mature enough in order to be released we are releasing it by using maven-release-plugin (mvn release:clean release:prepare release:perform) so that our project version will be transformed from Major.Minor.BuildVersion-SNAPSHOT (e.g. 1.0.0-SNAPSHOT) to Major.Minor.BuildVersion (e.g. 1.0.0), then will be prepared for the next development iteration like: Major.Minor.BuildVersion+1-SNAPSHOT (e.g. 1.0.1-SNAPSHOT)
The problems we are facing are related to projects versioning.
So, during the development phase on the trunk, all the projects are using the latest SNAPSHOT versions of their dependencies (mvn versions:use-latest-versions -DallowSnapshots=true -DupdateDependencies=true), but when we consider it's time to start the release procedure and prepare to branch the code, there problems start:
we are start branching
parent-pom
(mvn -B release:clean release:branch -DbranchName=${project.artifactId}_${project.version} -Dusername=${username} -Dpassword=${passwd} -Dproject.rel.${groupId}:${projectId}=1.0.0-SNAPSHOT
-Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT)- copy project from trunk to new created branch, transform pom version on trunk from 1.0.0-SNAPSHOT to 1.1.0-SNAPSHOT
non-dependent projects
(mvn -B release:clean release:branch -DbranchName=${project.artifactId}_${project.version} -Dusername=${username} -Dpassword=${passwd} -Dproject.rel.${groupId}:${projectId}=1.0.0-SNAPSHOT
-Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT versions:update-parent
-DallowSnapshots=true)- copy project from trunk to new created branch,
- transform the trunk pom version 1.0.0-SNAPSHOT become 1.0.1-SNAPSHOT
- update parent-pom.version: 1.0.0-SNAPSHOT become 1.1.0-SNAPSHOT
dependent projects:
(mvn -B release:clean release:branch -DbranchName=${project.artifactId}_${project.version} -Dusername=${username} -Dpassword=${passwd} -Dproject.rel.${groupId}:${projectId}=1.0.0-SNAPSHOT
-Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT versions:update-parent
-DallowSnapshots=true versions:use-latest-versions -DallowSnapshots=true
-DupdateDependencies=true)- copy project from trunk to new created branch
- transform pom version on trunk from 1.0.0-SNAPSHOT to 1.1.0-SNAPSHOT
- update parent-pom on trunk from 1.0.0-SNAPSHOT to 1.1.0-SNAPSHOT
- update the already branched dependency projects from 1.0.0-SNAPSHOT to 1.1.0-SNAPSHOT
The first problem here is that there is no way yet to have an argument to increase the MinorVersion when branch the project, the maven-release-plugin 2.2.2 does not increment the pom MinorVersion on trunk when branching, so that's why we need to use -Dproject.rel.${groupId}:${projectId}=1.0.0-SNAPSHOT
-Dproject.dev.${groupId}:${projectId}=1.1.0-SNAPSHOT arguments and change them manually for every project, so 200 times every time when we preapare for a new release.
I'm wondering if it's not a way to make all described procedure somehow in an automated fashion and to not need to perform all these changes manually all the time.
We've taking account even to modularize this product so that to colapse those 200 project in 100 probably, but this is not acceptable since the idea is to have a fine grained projects versioning and have all the projects with it's own lifecycle, so an aggregator (I mean a classic one) is out of discussion here.
We are using SVN as VCS, Maven as build tool (probably you already figured out about that :) ), and Bamboo as a CI server (actually, instead of "Maven Dependency Processor" feature, Bamboo is not helping me to much regarding the versioning problem).
Do you guys have any idea in order to find a proper solution for this problem, maybe another plugin which would help (versions-maven-plugin does not change versions automatically when branch), maybe another point of view for this, I don't know..., any help or sugestion are welcome.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我尽量避免将内部项目版本保留在父pom的
部分中,因为每次我发布项目时,${project.version }
变量将与项目的显式版本进行切换,例如:存储在父 pom 中,在项目 pom 中翻译,例如:${project.version},将变得1.0.1-SNAPSHOT 发布该项目时,将覆盖父 pom
中的
版本。因此,只要您不发布项目,将项目版本作为属性保存在像parent-pom这样的集中位置的技巧就有效。这是与分支问题严格相关的问题。
现在,如果您愿意,我可以告诉您有关使用此
> 当你开始发布父pom时,这是一个-SNAPSHOT版本,对吧?我的意思是,为了发布一个项目,您将首先发布它的所有依赖项及其相关的父pom,对吗?否则你的项目发布将会失败,因为它指向父 pom 的 -SNAPSHOT 版本。
替换来发布项目的更多信息:假设您想要发布您的 project_A,您将如何处理存储在父 pom
现在,您将释放父 pom,并将 project_A 的 -SNAPSHOT 版本保留在其
中,接下来您将释放 project_A< /strong>,您的项目将引用您的父 pom 新创建的发布版本,该父 pom 发布版本引用您的 project_A 的 -SNAPSHOT 版本,这仍然不是问题,因为您的父 pom 保留您的 project_A 的真实版本,直到您的 projectA 发布版本(比方说 1.0.0)将引用包含 1.0 的相同父 pom 发布版本您的 project_A 的 .0-SNAPSHOT 版本,现在您已经遇到问题了,因为您的父 pom
保留了错误的信息。当然,你可以在发布时破解父pom并存储project_A的发布版本,但这违反了规则,我根本不同意这一点,而且这是“破解”时的其他情况会带来更多的问题而不是帮助。
如果这听起来相当复杂和详细,我很抱歉,但我只是想尽可能多地解释现实生活中的情况,而不仅仅是理论上的,另外我还需要记住,我有 200 多个项目需要以某种方式保持一致。
I try to avoid keeping internal projects versions in the
<properties>
section of the parent-pom, since every time when I release a project, the<version>${project.version}</version>
variable will be switched with the explicit version of the project like:stored in parent pom, translated in the projects pom like: ${project.version}, will become 1.0.1-SNAPSHOT when release that project, and will overwrite the
<project_A.version>
version from parent-pom<properties>
. So this trick of keeping the projects versions as properties in a centralized location like the parent-pom, is valid as long as you don't release the projects.This is the question strictly related to the branching question.
Now, if you want I can tell you more about releasing the projects using this
<properties>
substitution:Lets's say you want to release your project_A, what will you do with the
<projectA.version>
stored in the parent pom<properties>
which is a -SNAPSHOT version when you start to release the parent pom, right? I mean, in order to release a project, you'll release all its dependencies and its related parent-pom first right? otherwise your project release will fail since is pointing to a -SNAPSHOT version of the parent pom.Now, you are releasing the parent-pom keeping the -SNAPSHOT version of project_A inside of it's
<properties>
, next when you'll release the project_A, your project will refer to the new created release version of your parent pom, which parent pom released version is refering to the -SNAPSHOT version of your project_A, still not a problem since your parent pom is keeping the true version of your project_A, until your projectA released version (lets say 1.0.0) will refer to the same parent pom released version which is containing 1.0.0-SNAPSHOT version of your project_A, and now you have a problem already because your parent pom<properties>
is keeping a wrong info.Ofcourse you can hack the parent pom when release it and store the release version of project_A, but this against the rules and I would not agree with that at all, plus that are other scenarios when this "hack" will cause more problems than help.
I'm sorry if this sounds pretty complicated and detailed but I just want to explain as much as possible the real life situation not just theoretical, plus that I also need to keep in mind that I have 200+ projects I need to keep somehow aligned.