How to use maven version plugin in branch - maven

I use maven version range for the dependencies in my parent pom.It works fine when I do a build on snapshot or a release.
But how should I need to proceed when I want to use the specific version of dependencies in a branch ?
For example: when I use version range such as (1.2.0,) it will always fetch the latest jar from the nexus repository. The latest would be like 1.2.5 as of when I do a release, since the dependencies are getting changed over and over.Now the latest version of my dependencies is 1.2.8-SNAPSHOT
In branch when I want 1.2.5 version for my dependencies, it is always looking for the latest one which is 1.2.5+
How to resolve this, while searching for similar questions I found that it could be resolved using maven-version-plugin. That requires a changes in the pom to add the plugin. But is there a solution without changing the pom and getting exact version for a dependency?
Any suggestions?

There is no solution without changing the pom at this point, if I understand the scenario correctly: In the release of a prior version of your product, the version of one (or more) of its dependencies was not fixated to the version available at the time. Now, in support of that previous release, the build has a different result than at the time of release.
There is no suggestion except to change the branch's pom to use the 'back' version available at the time of the release. Consider it a short term fix to a bug in the release process.

Related

Keeping jar version numbers in sync between JitPack and other repositories

I maintain a few Java library projects on GitLab, which I currently build with a GitLab CI workflow and deploy to a GitLab Maven repository. Now I would like to make them available via JitPack while keeping the GitLab Maven repo for a while.
GitLab’s Maven repo, like most of the others out there, uses the contents of the <version> tag in pom.xml for versioning. JitPack, on the other hand, needs a Git ref to work with (a branch name, a tag or a plain hash). I am looking for a way to use the same versioning regardless of the repo, so that version FOO will fetch a jar based on the same code, regardless of whether it is taken from GitLab or JitPack.
For a released, stable version that could be solved by tagging each release with its version number. That is, when I release version 3.7.0, I would ensure the <version> tag in my pom.xml reads 3.7.0, and tag the commit with 3.7.0 as well. I would need to enforce a match between the two (e.g. by teaching CI to bar{k|f} upon detecting a discrepancy), but with some homework, both repos would carry the same version of my code under the same version number.
Things get tricky when it comes to unstable versions. If I am working on the upcoming 3.7.2 release and would already like to make it available for testing, I understand common practice is to set the version tag to 3.7.2-SNAPSHOT, telling everyone that this is not a stable version. The GitLab Maven repo would serve the jar under that version.
For JitPack, versions ending in -SNAPSHOT indicate that the code could have changed since the last build and the jar should be rebuilt from source. A version named 3.7.2-SNAPSHOT would cause JitPack to look for a ref named 3.7.2 (tag or branch) and build it from scratch.
So I would have to ensure that the version name of the upcoming version resolves to the latest commit for the upcoming version. I could do that by developing the upcoming version in a branch named like the version, but that would presumably result in a naming conflict as I release it, as I would then introduce a tag with the same identifier.
Is there a general recommendation for addressing this, i.e. serving unstable versions of a jar via JitPack and a conventional Maven repo under the same version number?

Maven Version Range - downloads all the available versions not just the latest one

I have two modules: A and B.
A depends from B.
In the module A there is a dependency to B with the following version setting: [1.0.0,)
From the B there are two versions: 1.0.0-1 and 1.0.0-2. The 1.0.0-1 is out of date, it has some missing dependencies, hence I cannot create a build from it. But the 1.0.0-2 is working fine.
When I use the install for the module A I get an error that B:1.0.0-1 has a missing dependency.
That's happening because the maven downloaded all the versions from the 1.0.0 not just the last one.
If I would use LATEST then just the 1.0.0-2 would be downloaded, but it's not what I want. Basically I would like to download just the latest from the 1.0.0.
How could I do this ?
Thank you for the answers!
(Maven version: 3.5.0)
First don't use versions ranges cause they make your build non reproducible.. If you like to update things like that you can use versions-maven-plugin to update the dependency. Apart from that what is the difference between 1.0.0-1 and 1.0.0-2..From your explanations i would assume you should change your versions schema cause the second one is not compatible with the first one so I would say 2.0.0 instead of 1.0.0-2..or is see it as a bug fix than 1.0.1...(following semver). Another point LATEST is marked deprecated for a long time and will produce a WARNING in the next Maven versions..
Coming to you explanations: I have my doubts that all artifacts are being downloaded...If you take a look at the logging output I assume there are some line saying ...maven-metadata.xml will be downloaded...
First part of the answer...

Is it possible to use revapi maven plugin to do check against a SNAPSHOT version?

I'm currently setting up revapi-maven-plugin for a project, using latest version (0.7.0), and we want to check on our jenkins that no regression appears in our API during development.
Then for my process I don't want to check the regression between a snapshot and a release but between two snapshots.
Unfortunately (?) we use a different repository for our snapshots and our releases, and apparently revapi-maven-plugin seems not able to get the latest snapshot version from the snapshot repo.
Or is it and I did not understand how to do that?
I already put those value in my configuration but it does not change anything:
<alwaysCheckForReleaseVersion>false</alwaysCheckForReleaseVersion>
<oldVersion>LATEST</oldVersion>
This is supported since the version 0.8.0 of the revapi-maven-plugin.
The documentation of the oldVersion property reads (https://revapi.org/modules/revapi-maven-plugin/check-mojo.html#oldVersion):
If you don't want to compare a different artifact than the one being built, specifying just the old version is simpler way of specifying the old artifact. The default value is "RELEASE" meaning that the old version is the last released version of the artifact being built (either remote or found locally (to account for artifacts installed into the local repo that are not available in some public remote repository)). The version of the compared artifact will be strictly older than the version of the new artifact. If you specify "LATEST", the old version will be resolved to the newest version available remotely, including snapshots (if found in one of the repositories active in the build). The version of the compared artifact will be either older or equal to the version of the new artifact in this case to account for comparing a locally built snapshot against the latest published snapshot.

how do i tell maven to get latest version of artifact from custom nexus repository

i have following requirement.
i need to download the latest version of artifact from custom nexus repository rather than snapshot repository.
please suggest
Thanks.
To get the latest version of any artifact, just omit the <version> tag from the dependency. This way maven will always fetch the latest version of this artifact from the remote repo.
Warning: Keep in mind that this is not the preferred way to handle dependencies nor it is the proper flow of dependency management. By keeping the version number open ended, there is a very high probability that your project may fetch a particular version of any library that is now not backward compatible and may break your functionality in the project. It is, therefore, always recommended to specify a particular version number of all artifacts that are required for any application and when updating any library version, one should properly test it.
EDIT
For maven3 you can use the facility of an open ended version tag. Something like this
<version>[1.12.4,)</version>
Take a look into this page for further details about version ranges
According to this issue: https://issues.apache.org/jira/browse/MNG-3092 snapshots cannot be excluded (at least until this is fixed).

Is there a way to tell maven to always use the latest _stable_ version of a dependency?

How can I tell maven to always use the latest stable version of a dependency?
I know that I can depend on latest release version or just the latest version whatever that is from this question. I also know I can use the dependency plugin (also from that link).
However, I use google's guava library which seems to get an update every week. I find myself updating the version all the time. It's the google versioning system where it is more an incremental update than a big bang update and thus it is very unlikely that it will break anything especially given the nature of this library.
So I Would like to not have to keep changing the version identifier of my maven dependency.
So I could do this:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>[12.0.1,)</version>
</dependency>
Which would give me version 12.0.1 and later... and since I don't depend on any repos that are going to supply any snap shot versions of this dependency this will ensure I always have the latest release version.
However, it will also give me the "rc" versions as well (13.0-rc1 and 13.0-rc2). This is what I want to avoid.
Is it possible to make maven only depend on the stable release? i.e. that don't have any "rc" or "beta" or "alhpa" in their name and are just plain "13.0".
You can use RELEASE value in version element for your dependency to make Maven use the latest released version. However this is not the best practice, because it can break build reproduceability.
Also, Maven don't make logical differences between versions like 12.0.1 and 13.0-rc1. From Maven's point of view both of them are released versions and basically what you're trying to do is breaking Maven releases ideology in several ways.
So, instead of versioning artifacts like 13.0-rc1, you should do a regular releases and use special repositories and artifact promotion process as par of your release. So, you could have a release-candidates repository that can be used during testing and once test pass you'll promote those artifacts to a final release repository. But if you need to make changes, you'll just update released version, so 13.0, 13.0.1, etc...
mvn versions:use-latest-releases -Dexcludes="*:*:*:*:*-M*,*:*:*:*:*RC*,*:*:*:*:*rc*,*:*:*:*:*-alpha*,*:*:*:*:*-beta*,*:*:*:*:20030203.000550,*:*:*:*:*Beta*"

Resources