問題描述
Maven 發布和版本 Maven 插件 (Maven release and versions maven plugin)
What is the numbering/versioning strategy for dependencies when doing snapshots/releases?
A team of 15 developers,20 Maven parent projects = total 70+ POMs including child module POMs. Currently there are a lot of dependencies where most of these 70 depend on one or the other.
Past:
All POMS have 1.0.0‑SNAPSHOT
as their version and also under dependencies tags.It gets uploaded to Nexus repo with mvn deploy
.
Present:
We started doing mvn release
recently. So all 20 parent POMs are now 1.0.1‑SNAPSHOT
and release ver 1.0.0
for all of them lies in Nexus.All <dependencies>
tags now point to 1.0.0
Problem:
Developers don't want to point to release versions. They need bleeding edge development version 1.0.X‑SNAPSHOT
from their peers whether its unstable or not.
SCM wants to point to RELEASE
versions only as he has to do a mvn release
once a week which will fail as it points to snapshot versions.
Question:
Now I know the version plugin , but the question is, what do I put in the POM so that both parties are satisfied by running their own version of mvn versions:
command. Preferably, the POMs should point to SNAPSHOTS so 15 people are happy, and when SCM does the release, he can run a mvn versions:something
and everything gets converted to RELEASE
versions in place of SNAPSHOTS
. Then back to SNAPSHOTS for developers.
‑‑‑‑‑
參考解法
方法 1:
I am putting this as an answer, even though at present this is not quite working answer.
When I added the completionGoals
configuration option in the Maven Release Plugin, my aim was to enable the work‑flow where development used version ranges, but that releases would be pinned to concrete versions only.
One of the enabling goals that was added to the Versions Maven Plugin was the versions:resolve‑ranges
goal. What is missing is a way to unresolve those ranges again afterwards.
We don't really have anywhere safe to stash the originating ranges that the release plugin will not object to or clean up before we need it again.
The closest solution I have thought of is to inject XML PI's beside the version containing the version range... in such a situation, the pom.xml
would get transformed from, e.g.
<project>
...
<dependencies>
...
<dependency>
<groupId>com.foo.bar</groupId>
<artifactId>manchu</artifactId>
<version>[1.2.3,2.0)</version>
</dependency?
...
</dependencies>
...
</project>
to
<project>
...
<dependencies>
...
<dependency>
<groupId>com.foo.bar</groupId>
<artifactId>manchu</artifactId>
<version>1.5.7</version>
<?versions‑maven‑plugin allowed‑version‑range="[1.2.3,2.0)"?>
</dependency?
...
</dependencies>
...
</project>
by ensuring that the preparationGoals
included the versions:resolve‑ranges
goal... (Note: the versions plugin might have to fork a third Maven to work around the lack of pom.xml
reloading in order to have the clean verify
be meaningful, though resolve‑ranges
is supposed to resolve in the exact version that the build is working with, so it shouldn't be an issue).
Then in completionGoals
you have the (as yet unimplemented) versions‑maven‑plugin goal that removes the XML PI's and puts the ranges back in place.
There are a number of issues preventing this at present:
Unsure if the Maven Release Plugin's pom rewriting will remove the XML PI's (needs testing to confirm)
The XML parsing library in versions‑maven‑plugin is hacky at best, and a better solution is needed to enable the XML PI injection
My son demands attention, leaving very little time for me to attend to these issues.
However, you might be able to codge something together.
Set
completionGoals
to something likeversions:use‑next‑snapshots versions:commit
Run your releases like so
mvn versions:use‑releases versions:commit scm:commit release:prepare release:perform install
So what should happen:
We switch the
‑SNAPSHOT
s to releasesWe commit the change to SCM
We start the release preparation
When the
pom.xml
is transformed to the next development version, we also advance the dependencies (using the fact that all our dependencies had the exact same command (with theinstall
at the end) so their next‑SNAPSHOT
is already in the local repository, so they will get advanced for us automatically (in theory)) and we rely onrelease:prepare
to commit the changes for us.The release is performed as normally
We install the next development
‑SNAPSHOT
into the local repo so that all the down‑stream projects will get their version of this updated when they runversions:use‑next‑snapshots
The above is slightly error prone... I'd far prefer if I could offer you the version range based solution, but, well right now this is the best solution I can see.
(by Pulak Agrawal、Stephen Connolly)