All Projects → nemerosa → Versioning

nemerosa / Versioning

Licence: mit
Gradle plug-in to generate version information from the SCM branch (Git or Svn)

Programming Languages

groovy
2714 projects

Projects that are alternatives of or similar to Versioning

Reckon
Infer a project's version from your Git repository.
Stars: ✭ 124 (-21.02%)
Mutual labels:  gradle, gradle-plugin, versioning
Maven Git Versioning Extension
This extension will virtually set project versions, based on current git branch or tag.
Stars: ✭ 178 (+13.38%)
Mutual labels:  gradle, gradle-plugin, versioning
Axion Release Plugin
Gradle release & version management plugin.
Stars: ✭ 372 (+136.94%)
Mutual labels:  gradle, gradle-plugin, versioning
Jib
🏗 Build container images for your Java applications.
Stars: ✭ 11,370 (+7142.04%)
Mutual labels:  gradle, gradle-plugin
Okbuck
OkBuck is a gradle plugin that lets developers utilize the Buck build system on a gradle project.
Stars: ✭ 1,513 (+863.69%)
Mutual labels:  gradle, gradle-plugin
Clojurephant
Clojure and Clojurescript support for Gradle
Stars: ✭ 118 (-24.84%)
Mutual labels:  gradle, gradle-plugin
Gradle Changelog Plugin
Plugin for parsing and managing the Changelog in a "keep a changelog" style.
Stars: ✭ 102 (-35.03%)
Mutual labels:  gradle, gradle-plugin
Forma
Meta build system with Android and Gradle support.
Stars: ✭ 127 (-19.11%)
Mutual labels:  gradle, gradle-plugin
Bytex
ByteX is a bytecode plugin platform based on Android Gradle Transform API and ASM. 字节码插件开发平台
Stars: ✭ 2,140 (+1263.06%)
Mutual labels:  gradle, gradle-plugin
Poetry Dynamic Versioning
Plugin for Poetry to enable dynamic versioning based on VCS tags
Stars: ✭ 131 (-16.56%)
Mutual labels:  versioning, subversion
Kotlin Gradle Plugin Template
🐘 A template to let you started with custom Gradle Plugins + Kotlin in a few seconds
Stars: ✭ 141 (-10.19%)
Mutual labels:  gradle, gradle-plugin
Godot
Keep track of how much time you spend on Gradle builds
Stars: ✭ 113 (-28.03%)
Mutual labels:  gradle, gradle-plugin
Gradle Build Properties Plugin
Keep your secrets secret. External build properties support for your Gradle scripts.
Stars: ✭ 110 (-29.94%)
Mutual labels:  gradle, gradle-plugin
Gradle Nexus Staging Plugin
Automatize releasing Gradle projects to Maven Central.
Stars: ✭ 132 (-15.92%)
Mutual labels:  gradle-plugin, continuous-delivery
Gradle Android Plugin
[Deprecated] Gradle Android Plugin 中文版使用手册,如有纰漏,望斧正
Stars: ✭ 155 (-1.27%)
Mutual labels:  gradle, gradle-plugin
Jenkins Pipeline Shared Libraries Gradle Plugin
Gradle plugin to help with build and test of Jenkins Pipeline Shared Libraries (see https://jenkins.io/doc/book/pipeline/shared-libraries/)
Stars: ✭ 103 (-34.39%)
Mutual labels:  gradle, gradle-plugin
Gradle Eclipse Aar Plugin
Gradle plugin to use Android AAR libraries on Eclipse.
Stars: ✭ 127 (-19.11%)
Mutual labels:  gradle, gradle-plugin
Gradle Aem Plugin
Swiss army knife for Adobe Experience Manager related automation. Environment setup & incremental AEM application build which takes seconds, not minutes.
Stars: ✭ 145 (-7.64%)
Mutual labels:  gradle, gradle-plugin
Vertx Gradle Plugin
An opinionated Gradle plugin for Vert.x projects
Stars: ✭ 98 (-37.58%)
Mutual labels:  gradle, gradle-plugin
Kordamp Gradle Plugins
A collection of Gradle plugins
Stars: ✭ 100 (-36.31%)
Mutual labels:  gradle, gradle-plugin

versioning

Gradle plug-in to generate version information from the SCM branch.

Use cases

Given a simple release workflow:

Release workflow

We get the version information from the branch in two flavours:

  • the full version, which is normalised branch name, followed by the short commit hash
  • the display version, which can be used to display the version to an end user, and is computed differently on a feature/* or master branch than on a release/* branch.

The computed project's display version on the feature/* and master branches is the base version (the normalised branch name without the prefix) and the abbreviated commit hash (or build version). For release/* branches, the version is computed according the latest tag on the branch, allowing for automatic patch number.

To achieve such a configuration, just configure the versioning plug-in the following way and follow strict conventions for your branch names:

allprojects {
   version = versioning.info.full
}

// Using versioning.info.display for generating property files for example

Applying the plug-in

The versioning plug-in is hosted in JCenter and is registered in the Gradle Plug-in Portal.

Gradle 2.1 and higher

plugins {
   id 'net.nemerosa.versioning' version '2.8.2'
}

Gradle 1.x and 2.0

buildscript {
   repositories {
      maven {
         url "https://plugins.gradle.org/m2/"
       }
   }
   dependencies {
      classpath 'net.nemerosa:versioning:2.8.2'
   }
}

apply plugin: 'net.nemerosa.versioning'

Change log

Change log is available in the Wiki.

Using the versioning info

For example, to set the project's full version using the SCM:

version = versioning.info.full

For a multi module project, you will probably do:

allprojects {
   version = versioning.info.full
}

Versioning info

Once the versioning plug-in has been applied, a versioning extension is available for the project.

Getting the read-only ìnfo provides access to the following information, computed from the SCM information:

Property Description Git: master Git: feature/great Git: release/2.0
scm SCM source git git git
branch Branch name master feature/great release/2.0
branchType Type of branch master feature release
branchId Branch as an identifier master feature-great release-2.0
commit Full commit hash 09ef6297deb065f14704f9987301ee6620493f70 09ef6297deb065f14704f9987301ee6620493f70 09ef6297deb065f14704f9987301ee6620493f70
build Short commit/revision indicator, suitable for a build number 09ef629 09ef629 09ef629
full Branch ID and build master-09ef629 feature-great-09ef629 release-2.0-09ef629
base Base version for the display version `` great 2.0
gradle Project's version
display Display version master great 2.0.0, 2.0.1, ...
tag (1) Current tag (2) (2) (2)
lastTag (1) Last tag (4) (4) (4)
dirty Current state of the working copy (3) (3) (3)
versionNumber Version number containing major, minor, patch, qualifier and versionCode
versionNumber.major Major version 0 0 2
versionNumber.minor Minor version 0 0 0
versionNumber.patch Patch version 0 0 0, 1, 2, ...
versionNumber.qualifier Version qualifier (alpha, beta, engineer, ...) '' '' ''
versionNumber.versionCode Version code 0 0 20000, 20001, 20002, ...

(1) not supported for Subversion (2) will be the name of the current tag if any, or null if no tag is associated to the current HEAD. (3) depends on the state of the working copy the plug-in is applied to. true if the working copy contains uncommitted files. (4) Name of the last tag on the branch. It can be on the current HEAD but not necessarily - it will be null if no previous tag can be found. The last tags are matched against the lastTagPattern regular expression defined in the configuration. It defaults to (\d+)$, meaning that we just expect a sequence a digits at the end of the tag name.

Display version

The display version is equal to the base property is available or to the branch identifier.

For branches to type release, an additional computation occurs:

  • if no tag is available on the branch which has the base as a prefix, the display version is the base version, suffixed with .0
  • if a tag is available on the branch which has the base as a prefix, the display version is this tag, where the last digit is incremented by 1

By using the display version when tagging a release, the display version will be automatically incremented, patch after patch, using the release base at a prefix.

Version number

Version number is a container of several numbers computed from display by default . It is hosting major, minor, patch, qualifier and versionCode.

  • In a tag like 1.2.3, then major is 1, minor is 2 and patch is 3
  • Qualifier are taken from tags formatted like 1.2-beta.0 where qualifier is -beta here
  • Version code is a integer computed from major, minor and patch version.
    • 1.2.3 will give 10203
    • 21.5.16 will give 210516
    • 2.0-alpha.0 will give 20000

Tasks

The versioning plug-in provides two tasks.

versionDisplay

Displays the version information in the standard output. For example:

> ./gradlew versionDisplay
:versionDisplay
[version] scm        = git
[version] branch     = release/0.3
[version] branchType = release
[version] branchId   = release-0.3
[version] commit     = da50c50567073d3d3a7756829926a9590f2644c6
[version] full       = release-0.3-da50c50
[version] base       = 0.3
[version] build      = da50c50
[version] gradle     = 0.3.0
[version] display    = 0.3.0
[version] tag        =
[version] lastTag    = 0.2.0
[version] dirty      = false
[version] versionCode = 0
[version] major       = 0
[version] minor       = 0
[version] patch       = 0
[version] qualifier   = 

versionFile

Creates a file which contains the version information. By default, the file is created at build/version.properties and contains the following information:

> ./gradlew versionFile
> cat build/version.properties
VERSION_BUILD=da50c50
VERSION_BRANCH=release/0.3
VERSION_BASE=0.3
VERSION_BRANCHID=release-0.3
VERSION_BRANCHTYPE=release
VERSION_COMMIT=da50c50567073d3d3a7756829926a9590f2644c6
VERSION_GRADLE=0.3.0
VERSION_DISPLAY=0.3.0
VERSION_FULL=release-0.3-da50c50
VERSION_SCM=git
VERSION_TAG=
VERSION_LAST_TAG=0.2.0
VERSION_DIRTY=false
VERSION_VERSIONCODE=0
VERSION_MAJOR=0
VERSION_MINOR=0
VERSION_PATCH=0
VERSION_QUALIFIER=

This makes this file easy to integrate in a Bash script:

export $(cat build/version.properties | xargs)

The versionFile task can be customised with two properties. The defaults are given below:

versionFile {
   // Path to the file to be written
   file = new File(project.buildDir, 'version.properties')
   // Prefix to apply to the properties
   prefix = 'VERSION_'
}

Customisation

The collection of the versioning info can be customised by setting some properties in the versioning extension.

The default properties are shown below:

versioning {
   /**
    * Defines the SCM to use in order to collect information.
    *
    * At the moment, only Git (git) and Subversion (svn) are supported.
    */
   scm = 'git'
   /**
    * Computation of the release type and the base, by parsing the scm info.
    * By default, we use "/" as a separator in branch name between the type and the base. If not
    * present, the type is the branch and the base is empty.
    * F.e. if you want use tag name instead of branch you may provide something like:
    */
    releaseParser = { scmInfo, separator = '/' ->
        List<String> part = scmInfo.tag.split('/') + ''
        new net.nemerosa.versioning.ReleaseInfo(type: part[0], base: part[1])
    }
    /**
     * Fetch branch name from environment variables. Useful when using CI like
     * Travis or Jenkins.
     */
    branchEnv = ['TRAVIS_BRANCH', 'GIT_BRANCH', 'SVN_BRANCH', 'BRANCH_NAME']
    /**
     * Computation of the full version
     */
    full = { scmInfo -> "${scmInfo.branch}-${scmInfo.abbreviated}" }
    /**
     * Set of eligible branch types for computing a display version from the branch base name
     */
    releases = ['release']
    /**
     * Pattern used to match when looking for the last tag. By default, checks for any
     * tag having a last part being numeric. At least one numeric grouping
     * expression is required. The first one will be used to reverse order
     * the tags in Git.
     */
    lastTagPattern = /(\d+)$/
}

Dirty versions

The behaviour of the version computation is slightly different when the working copy is dirty - meaning that the working copy contains some files which are not staged or not committed.

When the working copy the version is computed from, the default behaviour is to append the -dirty suffix to the display and full version.

This can be customised with the following attributes on the versioning extension:

versioning {

   /**
   * Dirty mode.
   *
   * Closure that takes a version (display or full) and processes it to produce a <i>dirty</i>
   * indicator. By default, it appends the dirtySuffix value to the version.
   */
   dirty = { version -> "${version}${dirtySuffix}" }

   /**
   * Default dirty suffix
   */
   dirtySuffix = '-dirty'

   /**
   * If set to true, the build will fail if working copy is dirty and if the branch type is
   * part of the releases list ("release" only by default).
   */
   dirtyFailOnReleases = false

   /**
    * If set to true, no warning will be printed in case the workspace is dirty. Default is
    * to print a warning.
    */
   noWarningOnDirty = false
}

Snapshots

Recomended configuration for development with -SNAPSHOT, for details see below.

versioning {
   releaseBuild = false		// own control, which build is really release, set to true in CI-server release job
   releaseMode = 'snapshot'	// how to compute version on release-branches
   displayMode = 'snapshot'	// how to compute version on non-release-branches
   dirty = { t -> t }		// switch off dirty-suffix ( could be usefull for local development )
}

Snapshots on release branches

Sometimes, you do not want to have the display version for a release branch being the next tag if you are already on a tag. ( release branch is defined in the releases-set. )

By default, the versioning plug-in will behave correctly if you tag only as the very end of your delivery pipeline, when the project is actually delivered. But if you want to tag upfront, you probably need to indicate that your display version is a snapshot or similar (see issue [#19|https://github.com/nemerosa/versioning/issues/19] for the discussion).

In such a case, you can specify a snapshot release mode:

versioning {
   releaseMode = 'snapshot'
}

In this case, if the HEAD is not exactly associated with a tag, the -SNAPSHOT string will be appended to the display version. For example, if there is a previous tag 2.1.0, then the display version will be 2.1.1-SNAPSHOT. But if the HEAD is exactly on the 2.1.0 tag, then the display version is also 2.1.0.

You can customise the -SNAPSHOT suffix used the snapshot property:

versioning {
   releaseMode = 'snapshot'
   snapshot = '.DEV'
}

Note that the default releaseMode is tag, where the next tag is always used as a display version.

You can also customise completely the computation of the display version for a release by setting the releaseMode to a Closure:

versioning {
   releaseMode = { nextTag, lastTag, currentTag, extension ->
       "${nextTag}"
   }
}

The meaning of the parameters is illustrated by the diagrams below:

Release tags

  • nextTag = 2.1.2 - computed
  • lastTag = 2.1.1 - last tag from the HEAD
  • currentTag = 2.1.1 - exact tag for the HEAD

Release tags

  • nextTag = 2.1.1 - computed
  • lastTag = 2.1.0 - last tag from the HEAD
  • currentTag = none - exact tag for the HEAD

The extension parameter is the content of the versioning configuration object.

Note that the display mode based on the current tag is not supported in Subversion. It is kind of tricky to get the tag associated to a given revision.

If You want to have more control when release or snapshot build is performed, You can use releaseBuild boolean property. This is usefull in case of usage central maven repository, which forbids replacement of released final artifacts.

versioning {
   releaseBuild = false // this could be set as build argument of gradle
   releaseMode = 'snapshot'
}

Snapshots on non-release branches

Non-release branches are all which doesn't exists in release-set. In case you prefer maven way for creating artifacts and You want to use -SNAPSHOT suffix , it's recomended to use displayMode.

versioning {
   displayMode = 'snapshot'
}

Possible values for displayMode are defined as closures :

DISPLAY_MODES = [
    full    : { branchType, branchId, base, build, full, extension ->
                "${branchId}-${build}"
              },
    snapshot: { branchType, branchId, base, build, full, extension ->
                "${base}${extension.snapshot}"
              },
    base    : { branchType, branchId, base, build, full, extension ->
                base
              },
]

You can use also use own display mode defined as a closure :

versioning {
   displayMode = { branchType, branchId, base, build, full, extension ->
                "${branchType}-${base}${extension.snapshot}"
            }
}

Version number

Version number computation can be customised by setting some properties in the versioning extension.

versioning {
    /**
     * Digit precision for computing version code.
     *
     * With a precision of 2, 1.25.3 will become 12503.
     * With a precision of 3, 1.25.3 will become 1250003.
     */
    int precision = 2

    /**
     * Default number to use when no version number can be extracted from version string.
     */
    int defaultNumber = 0

    /**
     * Closure that takes major, minor and patch integers in parameter and is computing versionCode number.
     */
    Closure<Integer> computeVersionCode = { int major, int minor, int patch ->
        return (major * 10**(2 * precision)) + (minor * 10**precision) + patch
    }

    /**
     * Compute version number
     *
     * Closure that compute VersionNumber from <i>scmInfo</i>, <i>versionReleaseType</i>, <i>versionBranchId</i>,
     * <i>versionFull</i>, <i>versionBase</i> and <i>versionDisplay</i>
     *
     * By default it tries to find this pattern in display : '([0-9]+)[.]([0-9]+)[.]([0-9]+)(.*)$'.
     * Version code is computed with this algo : code = group(1) * 10^2precision + group(2) * 10^precision + group(3)
     *
     * Example :
     *
     * - with precision = 2
     *
     * 1.2.3 -> 10203
     * 10.55.62 -> 105562
     * 20.3.2 -> 200302
     *
     * - with precision = 3
     *
     * 1.2.3 -> 1002003
     * 10.55.62 -> 100055062
     * 20.3.2 -> 20003002
     **/
    Closure<VersionNumber> parseVersionNumber = { SCMInfo scmInfo, String versionReleaseType, String versionBranchId,
                                                  String versionFull, String versionBase, String versionDisplay ->
        // We are specifying all these parameters because we want to leave the choice to the developer
        // to use data that's right to him
        // Regex explained :
        // - 1st group one digit that is major version
        // - 2nd group one digit that is minor version
        // - It can be followed by a qualifier name
        // - 3rd group and last part is one digit that is patch version
        Matcher m = (versionDisplay =~ '([0-9]+)[.]([0-9]+).*[.]([0-9]+)(.*)$')
        if (m.find()) {
            try {
                int n1 = Integer.parseInt(m.group(1))
                int n2 = Integer.parseInt(m.group(2))
                int n3 = Integer.parseInt(m.group(3))
                String q = m.group(4) ?: ''
                return new VersionNumber(n1, n2, n3, q, computeVersionCode(n1, n2, n3).intValue(), versionDisplay)
            } catch (Exception ignore) {
                // Should never go here
                return new VersionNumber(0, 0, 0, '', defaultNumber, versionDisplay)
            }
        } else {
            return new VersionNumber(0, 0, 0, '', defaultNumber, versionDisplay)
        }
    }

}

Detached and shallow clone support

When a repository is checked out in detached mode, the branch will be set to HEAD and both the display and full version will be set to HEAD-<commit> where <commit> is the abbreviated commit hash.

When a repository is checked out in shallow mode, no history is available and the display version for a release branch cannot be correctly computed. In this case, we have two situations:

  • if the HEAD commit has a tag, we use the tag name as display version
  • if it has no tag, we use the base version and the SNAPSHOT suffix, to indicate that the release exact version cannot be computed.

In both cases, the VersionInfo object contains a shallow property which is set to true.

External Git repository

In some very specific cases, the Git directory might be external to the project.

In order to support this case, you can specify the gitRepoRootDir property:

versioning {
    gitRepoRootDir = '/path/to/other/directory'
}

Subversion support

Subversion is supported starting from version 1.1.0 of the Versioning plug-in. In order to enable your working copy to work with Subversion, set scm to svn:

versioning {
   scm = 'svn'
}

The branches are read from under the branches/ folder and the branch type is parsed using '-' as a separator. The table below gives some examples for Subversion based branches:

Property Description SVN: trunk @ rev 12 SVN: branches/feature-great @ rev 12 SVN: branches/release-2.0 @ rev 12
scm SCM source svn svn svn
branch Branch name trunk feature-great release-2.0
branchType Type of branch trunk feature release
branchId Branch as an identifier trunk feature-great release-2.0
commit Revision 12 12 12
build Revision 12 12 12
full Branch ID and build master-12 feature-great-12 release-2.0-12
base Base version for the display version `` great 2.0
display Display version trunk great 2.0.0, 2.0.1, ...

The rules for the display mode remain the same ones than for Git.

Collecting the version information using Subversion will needs one remote access to the repository. Credentials can optionally be configured using following configuration parameters:

versioning {
   scm = 'svn'
   // Optional credentials
   user = 'xxx'
   password = 'xxx'
}

If credentials are not provided, the versioning plug-in will rely on the default Subversion configuration for the current user.

Release

The CI and release jobs are available in the Nemerosa Jenkins.

See http://plugins.gradle.org/submit for the publication on the Gradle Plug-in Portal.

Migration from 1.x to 2.x

  • SVN layer is now using SVNKit for support (before, Subversion needed to be installed)
  • the trustServerCert option for SVN is deprecated and should be removed

Contributions

Contributions are welcome - just create issues or submit pull requests.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].