/maven-git-versioning-extension

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

Primary LanguageJavaMIT LicenseMIT

Maven Git Versioning Extension

Maven Central

Build Workflow

Changelog

ℹ 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

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 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">

    <extension>
        <groupId>me.qoomon</groupId>
        <artifactId>maven-git-versioning-extension</artifactId>
        <version>LATEST</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 <updatePom> global enable(true)/disable(false) version update in original pom file.

  • <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
      • <pattern> An arbitrary regex to match property names
      • <value> The definition of the new property value
        • optional <pattern> An arbitrary regex to match property values
        • <format> The new value format of the property, see Version Format & Placeholders
    • 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
      • <pattern> An arbitrary regex to match property names
      • <value> The definition of the new property value
        • optional <pattern> An arbitrary regex to match property values
        • <format> The new value format of the property, see Version Format & Placeholders
    • 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
      • <pattern> An arbitrary regex to match property names
      • <value> The definition of the new property value
        • optional <pattern> An arbitrary regex to match property values
        • <format> The new value format of the property, see Version Format & Placeholders
    • considered if...
      • HEAD is detached git checkout <COMMIT> and no matching version tag is pointing to HEAD

Version Format & Placeholders

/ characters within final version will be replaced by -**

  • ${ref}

    • current ref name (branch name, tag name or commit hash)
  • ${branch} (only available within branch configuration)

    • The branch name of HEAD
    • e.g. 'master', 'feature/next-big-thing', ...
  • ${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', ...
  • ${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.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 by group name or group index e.g.
    • Named Group Example
      pattern = 'feature/(?<feature>.+)'
      versionFormat = '${feature}-SNAPSHOT'    
    • Group Index Example
      pattern = 'v([0-9].*)'
      versionFormat = '${1}'
  • ${version}

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

    • version set in pom.xml without -SNAPSHOT postfix
    • e.g. '1.0.0'
  • ${property.name}

    • name of matching property
    • Only available within property format.
  • ${property.value}

    • value of matching property
    • Only available within property format.

Parameters & Environment Variables

  • 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

Provided Project Properties

  • git.commit e.g. '0fc20459a8eceb2c4abb9bf0af45a6e8af17b94b'
  • git.ref value of branch of tag name, always set
    • 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

Miscellaneous Hints

Commandline To Print Project Version

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

CI/CD

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.

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

Changelog

4.1.0

4.0.0

  • Major Refactoring, Simplification
  • Also available as Gradle Plugin
  • New Provided Project Properties
    • git.ref value of branch of tag name, always set

Breaking Changes

  • Restructured XML Config
    • renamed root tag <configuration> -> <gitVersioning>
    • removed nested structure
    • see Configure Extension
  • Renamed Environment Variables
    • MAVEN_PROJECT_BRANCH -> VERSIONING_GIT_BRANCH
    • MAVEN_PROJECT_TAG -> VERSIONING_GIT_TAG
  • Renamed Maven Parameters
    • -Dproject.branch -> -Dgit.branch
    • -Dproject.tag -> -Dgit.tag
  • Removed Mave Parameters
    • -DgitVersioning - disable the extension by a parameter is no longer supported
  • Renamed Provided Project Properties
    • project.branch -> git.branch
    • project.tag -> git.tag
    • project.commit -> git.commit