David
David

Reputation: 81

Is there a good approach at automatically incrementing maven versions

I've been going at this for a while, and here's the current scenario:

For release, I suppose I could do something similar where I retrieve the version, then figure out a way to increment it -> publish back to the currently active branch -> and then finally do a deploy. Right now, I went with a slightly easier although error-prone approach: I attempt to fetch the current version set in the artifactory we use and, if it exists, I fail the pipeline with a message stating that the version already exists. It's not great right now, because I'm actually inverting an error condition here, so if maven fails for any other reason, it actually assumes the version doesn't exist and keeps on going to the next steps. Ugh.

Now, the main points I was looking for here are really around the best method of handling maven projects and versioning. Ideally my goals are:

I do have one restriction: the tooling we use does not allow for us to have merge hooks (Azure DevOps with Azure Git). This means we are limited to pipelines on pulls (and PRs), and after a PR is merged.

I'm happy to take any other approach here realistically, I feel like I'm going out of my way to make something that should have a clear path by now, so I'm hoping for someone with some guidance here.

Upvotes: 5

Views: 8468

Answers (4)

Kanagavelu Sugumar
Kanagavelu Sugumar

Reputation: 19270

This is working for me:

mvn build-helper:parse-version versions:set -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.nextIncrementalVersion} versions:commit

Upvotes: 1

taleodor
taleodor

Reputation: 2076

We built a tool (note: I'm working on it) to keep track of different versions, schemas and increments per branch.

You can define your schemas and your pins per branch. Also, you're not bound by SemVer, could use CalVer as well.

I.e., for SemVer you could set your project version to semver, while set branch pin for dev branch to Major.Minor.Patch-SNAPSHOT. Then it would increment your master branch with plain semver and dev branch will have -SNAPSHOT suffix.

There is either open source version here https://github.com/relizaio/versioning or SaaS version at https://relizahub.com (which has a lot of extra functionality). SaaS version is the one that would keep track of previous versions and allow you to do clean per-branch split via API.

Here is my write-up on details for all the above: https://worklifenotes.com/2020/02/27/automatic-version-increments-with-reliza-hub-2-strategies/

Note: This still needs a command in the end to inject version into your pom, for which the following may be used via Versions Maven Plugin (on top of suggestions from other answers):

mvn versions:set -DnewVersion="$versionFromReliza"

Upvotes: 0

khmarbaise
khmarbaise

Reputation: 97527

A supplemental for @davidxxx answer. The usage of build-helper maven plugin can improve that:

mvn build-helper:parse-version versions:set \
    -DnewVersion=\${parsedVersion.nextMajorVersion}.0.0 \
    versions:commit

or like this:

mvn build-helper:parse-version versions:set \
   - DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0 \
   versions:commit

without any sed etc. more details:

Upvotes: 7

davidxxx
davidxxx

Reputation: 131526

then use the update-versions command to inject the "-SNAPSHOT" to it and publish (I don't publish it back to the branch, since I don't really want to keep the "-SNAPSHOT".

Not a judgement but using a no snapshot version in the pom for both snapshot and release is error prone. Snapshot means "in dev, beware". Release means "quite stable, go". In cases of doubt or to rollaback to a specific version, devs have to be sure of what a commit refers to. Here it is blurry.

Ideally my goals> are:

be able to publish something as a SNAPSHOT properly (maybe without having to resort to maven-exec)?

Two ways :

  • keep your artifact version as -SNAPSHOT in your pom.xml and update it by stripping the -SNAPSHOT and tag/deploy it when you want consider it as a release.
  • keep your artifact version as no -SNAPSHOT (while I don't advise) and use the maven-ci friendly feature/plugin to set the version dynamically.

Your pom properties could look like a version defined as :

 <version>${revision}${sha1}${changelist}</version>

 <properties>
    <revision>1.0.0</revision>
    <changelist></changelist>
    <sha1/>
 </properties>

And you should also declare the flatten-maven-plugin to keep the pom.xml consumable by other projects (which is the case for libraries).

At last you could execute the deploy goal to push your snapshot in your remote maven repository:

mvn -Dchangelist=-SNAPSHOT clean deploy

be able to update my version incrementally, so users don't have to constantly have to update their version? This process of course would have to ensure I don't push something to master that may have the wrong version (which would then fail at deploying).

You could rely on maven plugins and scripting to achieve that.
For example to increment automatically the second digit of a version that doesn't have snapshot as prefix like in your case, on a linux system you can do :

// get the current pom version and store it into a variable
version=$(mvn -q -U -Dexpression=project.version -DforceStdout maven-help-plugin:evaluate)
// increment the second digit of the version and overwrite the variable
version=$(echo ${version} |  awk -F'.' '{print $1"."$2+1"."$3}' |  sed s/[.]$//)
// update the pom with the new version
mvn -U versions:set -DnewVersion=${version}

It works both for versions with 3 digits but also 2 digits thanks to the sed.

Upvotes: 6

Related Questions