Code Monkey home page Code Monkey logo

versioning's Introduction

Project Versioning Plugin

Latest version Latest version

This Gradle Plugin will generate automatically project versions based on your repository's tags and commits.

It is a basic implementation of Semantic Versioning 2.0.0 recommendation and has been initially developed to adopt the suggested Google Play publishing scheme.

It works with Git version 2.x.

Why choosing this library?

Because it keeps the process simple, automatic and you can apply the plugin in any gradle-based project.

How does it work?

The plugin counts the number of commits with major or minor or patch keywords.

Let's say you have the following number of commits in your repository:
(The keyword here is [minor-change], but you can define your own keywords.)

"[minor-change] JIRA-01 Initial commit"
"[minor-change] JIRA-02 Pushing random code"

Then, the plugin will generate the version 0.2.0.
If you add a new commit with a [minor-change] keyword.

"[minor-change] JIRA-01 Initial update"
"[minor-change] JIRA-02 Pushing random code"
"[minor-change] JIRA-03 Adding a new random feature" <--

Then, the plugin will generate the version 0.3.0.
If you add a new commit with a [patch-change] keyword.

"[minor-change] JIRA-01 Initial update"
"[minor-change] JIRA-02 Pushing random code"
"[minor-change] JIRA-03 Adding a new random feature"
"[patch-change] JIRA-04 Fixing a previous feature" <--

Then, the plugin will generate the version 0.3.1.
If you add a new commit with a [minor-change] keyword.

"[minor-change] JIRA-01 Initial update"
"[minor-change] JIRA-02 Pushing random code"
"[minor-change] JIRA-03 Adding a new random feature"
"[patch-change] JIRA-04 Fixing a previous feature"
"[minor-change] JIRA-05 Adding a new random feature" <--

Then, the plugin will generate the version 0.4.0.
(When you increase the minor version, the patch version resets to 0)
If you add a new commit with a [major-change] keyword.

"[minor-change] JIRA-01 Initial update"
"[minor-change] JIRA-02 Pushing random code"
"[minor-change] JIRA-03 Adding a new random feature"
"[patch-change] JIRA-04 Fixing a previous feature"
"[minor-change] JIRA-05 Adding a new random feature"
"[major-change] JIRA-06 Adding an incompatible or big change" <--

Then, the plugin will generate the version 1.0.0.
(When you increase the major version, the minor and patch version reset to 0)

You can define your own keywords like [feature], [bug], [hotfix], etc.

Important!

Before you can start using the plugin, you must create a version tag in your repository.

git tag <tagname> // "version/0.7.0" for example from master
git push origin <tagname>

How to apply?

plugins {
    
    id 'com.chattylabs.versioning' version '<latest version>'
}

-or-

buildscript {
    
    repositories { 
    
        jcenter() 
        
        // Optional. Access to early versions.
        maven { url "https://dl.bintray.com/chattylabs/maven" }
    }
    
    dependencies {
    
        classpath 'com.chattylabs:versioning:<latest version>'
    }
}
    
apply plugin: 'com.chattylabs.versioning'

Now, setup the required and optional values in your gradle file.

versioning {
    
    tagPrefix "version/"                // Required
    
    keywords {
    
        major "[incompatible]"          // Optional. By default it never upgrades the major version.
        minor "[feature]"               // Required
        patch "[bug]"                   // Required
    }
}

The plugin will generate a version.properties file within the project's module.
You should add this file into your .gitignore config.

How to use?

The following functions are available:

versioning.name()                   // i.e. generates "0.1.0"  - string
versioning.code()                   // i.e. generates 000100   - integer
versioning.computedVersionCode()    // i.e. generates 725      - integer (based on the total number of commits)

To update to the last project version run:

./gradlew pullVersion

To create a new project version tag run:

./gradlew pushVersion

Where to use?

The followings are some platform examples:

Web

version = versioning.name()

Android

android {
    
    defaultConfig {
    
        [..]
        
        versionCode versioning.computedVersionCode()
        versionName versioning.name()
    }
}

iOS

afterEvaluate {
    
    // Use some (JVM) plist library such as Apache's common configuration http://commons.apache
    .org/proper/commons-configuration/ to update info.plist
    
    infoPlist.set(CFBundleShortVersionString, versioning.name())
    infoPlist.set(CFBundleVersion, "${versioning.computedVersionCode()}")
}

Notes

Setup

You must create an initial version tag in your repository following the tagPrefix you have setup and the current version of your project. Otherwise the build will throw an Exception.

git tag <tagPrefix + current version>   // i.e. "version/0.1.0" or "v0.1.0"
 
git push origin <tagPrefix + current version>

Increasing versions

The only rule to increase the version is that you add the keywords you have configured into the commit message.
If you push commits without the keywords, it won't be counted as a version upgrade.

Continuous Integration

If you are running the update through a Continuous Integration system, and you want to get the generated version, you can use the following bash function to read the version.properties.

function retrieveVersion() {
  if [ -f "$file" ]
  then
    printf "\"$file\" found."
    while IFS='=' read -r key value
    do
      eval ${key}=\${value}
    done < "$file" &> /dev/null
  else
    printf "\"$file\" not found."
  fi
}
 
file="./app/version.properties"
 
# Example of use
 
./gradlew :app:pullVersion :app:assemble
 
retrieveVersion  // <-- The function
 
versionName="${major#0}.${minor#0}.${patch#0}"
 
# Publish to Google Play Store / Apple Store / Bintray / Fastlane / HockeyApp ...
 
# To create a new version on the reposiroty. Needs repository write access.
./gradlew :app:pushVersion 
 
printf "New version <${versionName}> published successfuly"

Multiple modules

If you have several projects/modules into the same repository, and you want to generate a different version per project/module, you only need to establish a specific tagPrefix per module/version.

You also have to distinguish the projects/modules commits by a unique keyword.

versioning {
        
    tagPrefix "${project.name}-version/"      // Use a unique prefix per each module
        
    keywords {
    
        ...
        
        minor "[${project.name}-feature]"     // Use a unique keyword for the commits
    }
}

Extras

You can setup a different .git folder by applying the following option:

versioning {

    git { // Optional. You can specify a custom .git folder path
    
        dir new File("../another/different/.git/folder")
    }
}

ย 

versioning's People

Contributors

franriadigos avatar xvelx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

versioning's Issues

About the version properties file

Describe the bug

  • The file should be version.properties.
  • If the properties file doesn't exist, then it should be created based on the tag version.
  • The versioning.name() & versioning.code() should return the version stored in the properties file.
  • There should be a task called updateVersion which updates the version.properties file based on the last commits.
  • When running releaseVersion task, it should check the tag version, not the properties file.

Environment (please complete the following information):

  • Plugin version: 0.18.1

Version digits in the form of "09"

Is your feature request related to a problem? Please describe.

  • versioning.properties should contain digits in the form of 09, unless the sdk value.
  • Limit number should be 99
  • If patch version reaches the limit, the minor version should increase by 1
  • Major version initially would never increase automatically. It means that if the minor version reaches the limit, then an Exception must be thrown informing the amount the minor version should have increased by.

gradle releaseVersion task throws an error due to a RSA host key issue

Describe the bug
Execution failed for task :[module]:releaseVersion

Warning: Permanently added the RSA host key for IP address 'x.x.x' to the list of known hosts.

To Reproduce
Steps to reproduce the behaviour:
It seems to happen intermittently.. No way to reproduce for now.

Resources
https://blog.github.com/2013-08-25-ip-address-changes/
https://app.bitrise.io/build/f4874075c14da2a1

Environment (please complete the following information):

  • Platform: CI
  • Plugin version: 0.19.4

Add docs to code

Add inline documentation for codebase to make it easier for contribution.
Without documentation, it is hard to understand code without context.

Version resets and auto increases when reaching 99

Is your feature request related to a problem? Please describe.
Having more than 99 patches or bug fixes in a version doesn't work with the plugin because it resets and auto increases to the next version when it reaches the number 99

releaseVersion task needs written permissions

Is your feature request related to a problem? Please describe.
When running the ./gradlew releaseVersion task in the CI, it required me to grant written access for that repository.

I open this issue to see whether this behaviour is ok or we should consider alternatives.

requires git2

Describe the bug
The plugin does not find the initial version tag.

To Reproduce
Run the build on a CentOS-7 server.

Environment (please complete the following information):

  • Platform: Linux CentOS-7, Jenkins
  • Language: gradle-5, java11
  • Plugin version: 0.19.5

Additional context
The plugin uses the sort feature of git tag -l. This feature is available with git 2.x. Latest git version in standard CentOS-7 is 1.8.3.1 without the sort feature.

Please state the requirements in README.md to save ppl. a lot of time of bug hunting. Or at least promote the error messages of the git-call. The current version fails silently.

When having multiple modules it does not evaluate correctly the tag versions.

Describe the bug
The shell wildcard and regex might be wrong because it misses some tags with a specific number.

To Reproduce
Steps to reproduce the behaviour:

  1. Create tag any-version/0.14.0 or any-version/0.1.22
  2. Configure versioning {} block appropiately
  3. Build

Expected behavior
It should generate correctly the version

Environment (please complete the following information):

  • Plugin version: 0.19.3

Additional context
Already checked and fixed, but I write the issue for the record ๐Ÿ˜„

version.properties is created even when the version tag does not exist.

Describe the bug
After applying the plugin for the first time, the version.properties is created but the version tag doesn't exist.
This causes the exception to be thrown only once, after the properties file is created it never throws again.

Expected behavior
Until the version tag is created, the properties file creation shouldn't be processed.

Environment (please complete the following information):

  • Plugin version: 0.19.1

compatibility issue with Gradle 7.x

After update gradle to 7.x current plugin is broken.

When I try to execute updateVersion task I catch next problem:

* What went wrong:
A problem was found with the configuration of task ':updateVersion' (type 'UpdateVersionTask').
  - In plugin 'com.chattylabs.versioning' type 'com.chattylabs.plugin.UpdateVersionTask' property 'group' is missing an input or output annotation.
    
    Reason: A property without annotation isn't considered during up-to-date checking.
    
    Possible solutions:
      1. Add an input or output annotation.
      2. Mark it as @Internal.

Auto increase and reset version element

Major should be automatically increased by 1 when minor hits 99 and minor should be reset to 0.
Similarly minor should be increased by 1 when patch hits 99 and patch should be rest to 0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.