vivin / gradle-semantic-build-versioning

Gradle plugin to generate version-numbers and tags using semantic versioning
MIT License
85 stars 32 forks source link

add tagPattern as an optional project property #107

Closed ghost closed 4 years ago

ghost commented 5 years ago

adding the possibility to pass the tagPattern as an project property when running the task "printVersion". makes it possbile to create versions per branch / stage.

Added some documentation, sorry for not adding any tests for this, but it's my first code in groovy. 🤷‍♂

vivin commented 5 years ago

I will try to take a look at this either this week or weekend. Thanks!

ghost commented 5 years ago

@vivin sorry to bother you again, but do you have any updates on the PR? Thx

vivin commented 5 years ago

I will look at it today.

I am so sorry. I haven't been able to give this project the attention it deserves because I'm working full-time and working on my PhD (which I'm somewhat close to finishing).

vivin commented 5 years ago

@klimentstojanovada

I'm having a bit of trouble understanding the purpose of this feature. Why would you want to filter a different set of tags than what you already have in the configuration? Essentially, why would you want to override this property?

ghost commented 5 years ago

@vivin Hei, sorry if it was not clear. The problem I am trying to solve: to have different tags for different stages. so I want to have tags coupled together, create the version filtered by the "stage pattern", and creating tags with the "stage prefix"..

e.g. branch "dev" should generate semantic versions with prefix "dev" .. dev-2.0.0, dev-2.1.0

but branch "rc" should generate semantic versions with prefix "rc" based on the "rc" prefix tags... rc-1.0.0, rc-1.0.1

I want to change the version "generated" depending on the "stage" I am..

Therefore I want to dynamically change the tagPattern, to be able to generate a semantic Version for "dev" stage or "rc" stage.

at the moment I can use the plugin to create a tag the following way dynamically:

./gradlew tag -P push -P release -P tagPrefix="$[STAGE]"

what I am missing: is to create the version based on a dynamic "tagPattern"... something like that:

./gradlew printVersion -P tagPattern=~/^stage/

or perhaps I am missing a way to solve my use case without any modifications? .. hmmh 😕 hope this helps better to understand my use case.

ghost commented 5 years ago

@vivin hei, sorry to bother again.

any feedback?

I need this functionality to be able to use it for our use cases. Would love either to have it in your plugin or a workaround to achieve the same thing.

cheers

vivin commented 5 years ago

@klimentstojanovada

Sorry for the late response.

I think you are conflating version with tag. The version string will always be a pure semantic-version string, and tags are constructed using the version. This means that the version cannot have a prefix, as semantic versions do not have prefixes. Also, I'm not sure how you're getting ./gradlew tag -P push -P release -P tagPrefix="$[STAGE]" to work, as tagPrefix is not a project property.

However, they can have pre-release identifiers as suffixes. So it looks like that's what you're reaching for. This way you could have versions like 2.0.0-dev.0, 2.0.0-dev.1, and so on.

To use pre-release identifiers you need to set up a pre-release configuration first. Then you can use gradlew printVersion -P newPreRelease and it will include the pre-release identifier.

For your particular use-case (i.e., just 2.0.0-dev for example), you could do something like this (with some caveats):

preRelease {
    startingVersion = "$System.env.STAGE"

    bump = {
        ""
    }
}

bump is defined when you're going to be doing something like dev.0, dev.1, dev.2, and so on (see example here). Since you aren't doing that, you can just have bump return an empty string. But be careful, because this can lead to confusing and unexpected behavior when you attempt to bump the pre-release version. This can happen if you try to do it explicitly, or through the plugin's default behavior, due to no component being specified by either the bumpComponent property or via commit messages. In this situation the plugin will throw an error because it got back an empty string. To get around this, that is, if you're going to be doing something like 4.0.0-dev, 4.0.1-dev, and so on, you will need to "bump" by creating a new pre-release each time, which increments the patch number and appends the starting version of the pre-release identifier.

For example, let's say you have a dev branch. It's brand new and has no other releases and tags. The first version would be 1.0.0-dev, and you can print that by ./gradlew -P printVersion -P newPreRelease, and tag by doing ./gradlew tag -P newPreRelease. Now let's say you make additional changes and commit. You want the new version to be 1.0.1-dev, which you can do again by ./gradlew tag -P newPreRelease. But it isn't entirely clear what is going on (if you have this in a CI script especially) and so you can be more explicit (though redundant) by doing ./gradlew tag -P bumpComponent=patch -P newPreRelease every time you need to bump.

This workaround is admittedly hokey and there's probably a better way to do it. One approach might be to make bump optional. In this situation, if bump isn't provided and the existing version is a pre-release version, the default behavior could be just to bump the patch version and then append the pre-release starting-version (basically creating a new pre-release version each time).

EDIT

One more thing I wanted to point out. I'm a little averse to exposing tagPattern as a command-line option or property because this makes it extremely easy to mess things up if you have the wrong pattern -- for example, because of a typo, the pattern may end up matching none of the existing tags, leading the plugin to think that there are no previous versions, and thus causing it to attempt to create a tag for version 1.0.0. Of course, this is also possible if you have the wrong pattern in the config file, but there at least the pattern is visible and obvious (as are changes), and it's not as ephemeral when compared to specifying it via the command-line.