Maven Branch Versioning Extension


License

License

Categories

Categories

Maven Build Tools
GroupId

GroupId

com.qoomon
ArtifactId

ArtifactId

maven-branch-versioning-extension
Last Version

Last Version

3.1.3
Release Date

Release Date

Type

Type

maven-plugin
Description

Description

Maven Branch Versioning Extension
Maven Branch Versioning Extension
Project URL

Project URL

https://github.com/qoomon/maven-branch-versioning-extension
Source Code Management

Source Code Management

https://github.com/qoomon/maven-branch-versioning-extension.git

Download maven-branch-versioning-extension

How to add to project

<plugin>
    <groupId>com.qoomon</groupId>
    <artifactId>maven-branch-versioning-extension</artifactId>
    <version>3.1.3</version>
</plugin>

Dependencies

compile (3)

Group / Artifact Type Version
org.simpleframework : simple-xml jar 2.7.1
org.apache.maven : maven-plugin-api jar 3.5.0
org.eclipse.jgit : org.eclipse.jgit jar 4.9.0.201710071750-r

provided (2)

Group / Artifact Type Version
org.apache.maven : maven-core jar 3.5.0
org.apache.maven.plugin-tools : maven-plugin-annotations jar 3.5

test (4)

Group / Artifact Type Version
org.apache.maven.plugin-testing : maven-plugin-testing-harness jar 3.3.0
org.apache.maven : maven-compat jar 3.5.0
junit : junit jar 4.12
org.assertj : assertj-core jar 3.8.0

Project Modules

There are no modules declared in this project.

Maven Git Versioning Extension

Maven Central Changelog

Build Workflow LGTM Grade

ℹ Also available as Gradle Plugin

This extension will virtually set project versions, based on current Git branch or Git tag.

ℹ The pom files will not be modified, versions are modified in memory only.

  • Get rid of...
    • editing pom.xml
    • managing version by git and within files
    • Git merge conflicts

Example

Install

⚠️ minimal required maven version is 3.6.3

Add Extension

create or update ${basedir}/.mvn/extensions.xml file

<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 https://maven.apache.org/xsd/core-extensions-1.0.0.xsd">

    <extension>
        <groupId>me.qoomon</groupId>
        <artifactId>maven-git-versioning-extension</artifactId>
        <version>5.2.0</version>
    </extension>

</extensions>

ℹ Consider CI/CD section when running this extension in a CI/CD environment

Configure Extension

You can configure the final version format for specific branches and tags separately.

Create ${basedir}/.mvn/maven-git-versioning-extension.xml.

Example: maven-git-versioning-extension.xml

<gitVersioning>
    <branch>
        <pattern>master</pattern>
        <versionFormat>${version}</versionFormat>
    </branch>
    <branch>
         <pattern><![CDATA[feature/(?<feature>.+)]]></pattern>
         <versionFormat>${feature}-SNAPSHOT</versionFormat>
     </branch>
    <tag>
        <pattern><![CDATA[v(?<tagVersion>[0-9].*)]]></pattern>
        <versionFormat>${tagVersion}</versionFormat>
    </tag>
    <commit>
        <versionFormat>${commit.short}</versionFormat>
    </commit>
</gitVersioning>
  • optional <disable> global disable(true)/enable(false) extension.

    • Can be overridden by command option, see (Parameters & Environment Variables)[#parameters-&-environment-variables].
  • optional <updatePom> global enable(true)/disable(false) version update in original pom file.

    • Can be overridden by command option, see (Parameters & Environment Variables)[#parameters-&-environment-variables].
  • optional <preferTags> global enable(true)/disable(false) prefer tag rules over branch rules if both match.

  • <branch> specific version format definition.

    • <pattern> An arbitrary regex to match branch names (has to be a full match pattern e.g. feature/.+ )
    • <versionFormat> An arbitrary string, see Version Format & Placeholders
    • <property> A property definition to update the value of a property
    • optional <updatePom> Enable(true) or disable(false) version update in original pom fill (will override global <updatePom> value)
    • ⚠ considered if...
      • HEAD attached to a branch git checkout <BRANCH>
      • Or branch name is provided by environment variable or command line parameter
  • <tag> specific version format definition.

    • <pattern> An arbitrary regex to match tag names (has to be a full match pattern e.g. v[0-9].* )
    • <versionFormat> An arbitrary string, see Version Format & Placeholders
    • <property> A property definition to update the value of a property
    • optional <updatePom> Enable(true) or disable(false) version update in original pom fill (will override global <updatePom> value)
    • ⚠ considered if...
      • HEAD is detached git checkout <TAG>
      • Or tag name is provided by environment variable or command line parameter
  • <commit> specific version format definition.

    • <versionFormat> An arbitrary string, see Version Format & Placeholders
    • <property> A property definition to update the value of a property
    • ⚠ considered if...
      • HEAD is detached git checkout <COMMIT> and no matching version tag is pointing to HEAD

Format Placeholders

ℹ whole versionFormat will be slugified automatically, that means all / characters are replaced by -

  • ${ref}

    • current ref name (branch name, tag name or commit hash)
  • ${ref.slug}

    • like ${ref} with all / replaced by -
  • ${branch} (only available within branch configuration)

    • The branch name of HEAD
    • e.g. 'master', 'feature/next-big-thing', ...
  • ${branch.slug}

    • like ${branch} with all / replaced by -
  • ${tag} (only available within tag configuration)

    • The tag name that points at HEAD, if multiple tags point at HEAD latest version is selected
    • e.g. 'version/1.0.1', 'v1.2.3', ...
  • ${tag.slug}

    • like ${tag} with all / replaced by -
  • ${commit}

    • The HEAD commit hash
    • e.g. '0fc20459a8eceb2c4abb9bf0af45a6e8af17b94b'
  • ${commit.short}

    • The short HEAD commit hash (7 characters)
    • e.g. '0fc2045'
  • ${commit.timestamp}

    • The HEAD commit timestamp (epoch seconds)
    • e.g. '1560694278'
  • ${commit.timestamp.year}

    • The HEAD commit year
    • e.g. '2021'
  • ${commit.timestamp.month}

    • The HEAD commit month of year
    • e.g. '01'
  • ${commit.timestamp.day}

    • The HEAD commit day of month
    • e.g. '01'
  • ${commit.timestamp.hour}

    • The HEAD commit hour of day (24h)
    • e.g. '01'
  • ${commit.timestamp.minutes}

    • The HEAD commit minutes of hour
    • e.g. '01'
  • ${commit.timestamp.seconds}

    • The HEAD commit seconds of minute
    • e.g. '01'
  • ${commit.timestamp.datetime}

    • The HEAD commit timestamp formatted as yyyyMMdd.HHmmss
    • e.g. '20190616.161442'
  • Pattern Groups

    • Contents of group in the regex pattern can be addressed ${GROUP_NAME} or ${GROUP_INDEX}
    • ${GROUP_NAME.slug} or ${GROUP_INDEX.slug}
      • like ${GROUP_NAME} or ${GROUP_INDEX} with all / replaced by -
    • Examples
      • Named Group
        <branch>
          <pattern><![CDATA[feature/(?<feature>.+)]]></pattern>
          <versionFormat>${feature}-SNAPSHOT</versionFormat>
        </branch>
      • Group Index
        <tag>
          <pattern>v([0-9].*)'</pattern>
          <versionFormat>${1}</versionFormat>
        </tag>
  • ${version}

    • version set in pom.xml
    • e.g. '1.0.0-SNAPSHOT'
  • ${version.release}

    • like ${version} without -SNAPSHOT postfix
    • e.g. '1.0.0'
  • ${value} - Only available within property format

    • value of matching property

Parameters & Environment Variables

  • Disable Extension

    • Environment Variables
      • export VERSIONING_DISABLE=true
    • Command Line Parameters
      • maven ... -Dversioning.disable=true
  • Provide branch or tag name

    • Environment Variables
      • export VERSIONING_GIT_BRANCH=$PROVIDED_BRANCH_NAME
      • export VERSIONING_GIT_TAG=$PROVIDED_TAG_NAME
    • Command Line Parameters
      • maven ... -Dgit.branch=$PROVIDED_BRANCH_NAME
      • maven ... -Dgit.tag=$PROVIDED_TAG_NAME

    ℹ Especially useful for CI builds see Miscellaneous Hints

  • Update pom.xml

    • Environment Variables
      • export VERSIONING_UPDATE_POM=true
    • Command Line Parameters
      • maven ... -Dversioning.updatePom=true
  • Prefer Tags for Versioning instead of Branches

    • Environment Variables
      • export VERSIONING_PREFER_TAGS=true
    • Command Line Parameters
      • maven ... -Dversioning.preferTags=true

Provided Project Properties

  • git.commit e.g. '0fc20459a8eceb2c4abb9bf0af45a6e8af17b94b'
  • git.ref value of branch of tag name, always set
    • git.ref.slug like git.ref with all / replaced by -
    • git.branch e.g. 'feature/next-big-thing', only set for branch versioning
    • git.tag e.g. 'v1.2.3', only set for tag versioning
  • git.commit.timestamp e.g. '1560694278'
  • git.commit.timestamp.datetime e.g. '2019-11-16T14:37:10Z'
  • git.dirty repository's dirty state indicator true or false

Miscellaneous Hints

Commandline To Print Project Version

mvn --non-recursive exec:exec -Dexec.executable='echo' -Dexec.args='${project.version}' -q

Reproducible builds

The reproducible builds feature (https://maven.apache.org/guides/mini/guide-reproducible-builds.html) newly introduced in maven can be easily supported with this extension by using the latest commit timestamp as build timestamps.

<project.build.outputTimestamp>${git.commit.timestamp.datetime}</project.build.outputTimestamp>

IntelliJ Setup

For a flawless experience you need to disable this extension during project import. Disable it by adding -Dversioning.disable=true to Maven Importer VM options (Preferences > Build, Execution, Deployment > Build Tools > Maven > Importing > VM options for importer).

CI/CD Setup

Most CI/CD systems do checkouts in a detached HEAD state so no branch information is available, however they provide environment variables with this information. You can provide those, by using Parameters & Environment Variables. Below you'll find some setup example for common CI/CD systems.

GitHub Actions Setup

execute this snippet before running your maven command

if [[ "$GITHUB_REF" = refs/heads/* ]]; then
    export VERSIONING_GIT_BRANCH=${GITHUB_REF#refs/heads/};
elif [[ "$GITHUB_REF" = refs/tags/* ]]; then
    export VERSIONING_GIT_TAG=${GITHUB_REF#refs/tags/};
elif [[ "$GITHUB_REF" = refs/pull/*/merge ]]; then
    export VERSIONING_GIT_BRANCH=${GITHUB_REF#refs/};
    VERSIONING_GIT_BRANCH=${VERSIONING_GIT_BRANCH%/merge};
fi

GitLab CI Setup

execute this snippet before running your maven command

before_script:
  - if [ -n "$CI_COMMIT_TAG" ]; then
       export VERSIONING_GIT_TAG=$CI_COMMIT_TAG;
    else
       export VERSIONING_GIT_BRANCH=$CI_COMMIT_REF_NAME;
    fi

Jenkins Setup

execute this snippet before running your maven command

if [[ "$GIT_BRANCH" = origin/tags/* ]]; then
    export VERSIONING_GIT_TAG=${GIT_BRANCH#origin/tags/};
else 
    export VERSIONING_GIT_BRANCH=${GIT_BRANCH#origin/};
fi

Build

  - mvn install
  # run integration tests after install, 
  # integration tests will run with LATEST version of extension installed
  - mvn failsafe:integration-test

Versions

Version
3.1.3
3.1.2
3.1.1
3.0.0
2.6.0
2.5.0
2.4.0
2.3.2
2.3.1
2.3.0
2.0.0
1.0.2
1.0.1