vivin / gradle-semantic-build-versioning

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

How to bump and start a pre-release version? #110

Open JoshMcCullough opened 4 years ago

JoshMcCullough commented 4 years ago

Suppose the latest tag is 1.0.0 and I just made some changes which are destined for version 1.1.0. So I want to publish a pre-release package as version 1.1.0-alpha.0, but when I run ...

./gradlew tag -PbumpComponent=minor -PnewPreRelease

I get the error message:

Cannot create a tag for a snapshot version

I suppose I'm missing some understanding here. I've read through the documentation repeatedly but can't seem to figure out the proper usage via the command line. Is there other documentation/examples I might be missing?

vivin commented 4 years ago

Did you commit your changes?

You will also need to use release:

./gradlew tag -PbumpComponent=minor -PnewPreRelease -Prelease
JoshMcCullough commented 4 years ago

Yes -- committed. After adding -Prelease, I get a new error message:

Determined tag '0.1.0-alpha.0' is filtered out by your configuration; this is not supported. Check your filtering and tag-prefix configuration. You may also be bumping the wrong component; if so, bump the component that will give you the intended version, or manually create a tag with the intended version on the commit to be released.

Here is semantic-build-versioning.gradle:

startingVersion = '1.0.11'

matching {
    major = 0
    minor = 0
}

preRelease {
    startingVersion = 'alpha.0'
    pattern = /alpha/
    // The bumping scheme is alpha.0 -> alpha.1 -> ... -> alpha.n
    bump = {
        "alpha.${((it - ~/^alpha\./) as int) + 1}"
    }
}

I'm not sure why 0.1.0-alpha.0 is suggested at all since the startingVersion is 1.0.11. I expected the new version to be 1.1.0-alpha.0.

All of the existing tags in this project start with "v" but moving forward we are not using a prefix at all. not sure if this is causing issues or not.

vivin commented 4 years ago

This is kind of subtle and I should probably actually check for it and print out a warning/error. I kind of mention this in the documentation:

Note: Be careful when filtering tags because it can affect plugin-behavior. The plugin works by determining the base version from tags, so behavior can vary depending on whether certain tags have been filtered out or not:

  • If your filtering options are set such that none of the existing ancestor-tags match, the plugin will use the startingVersion.
  • If your filtering options are set such that the base version is not a pre-release version and you are attempting to use bumpComponent=pre-release, the build will fail.

So what is happening here is that you have your matching option configured to match only versions like 0.0.x, because both major and minor are set to 0. So this means that your starting version 1.0.11 would be filtered outright. That is, the tag that it is trying to generate would be excluded by your filtering configuration.

It's not clear why it's suggesting 0.1.0 though, because you have the starting version set as 1.0.11. It should be picking that up. Get rid of the matching section and try it again.

Also, what is the latest version tag you have on the repo?

UPDATE

Ok, I think I know what is happening. You probably have tags like 0.0.1 and so on. Since your matching is configured to match versions like 0.0.x, it will match those tags. Since there are tags it could find, it won't use startingVersion. For every 0.0.x tag, bumping the minor version as you're doing will result in 0.1.0. Finally, you have a preRelease configuration where the starting version is alpha.0. This is where 0.1.0-alpha.0 is coming from. However, that tag is excluded by your matching configuration. This is why you're seeing the error.

This is an interesting edge case because your configuration is inconsistent in multiple ways :):

  1. The startingVersion is excluded by your matching filter.
  2. The startingVersion will never be used because there are pre-existing tags that match your matching filter.
  3. You're trying to bump the latest version found by your matching filter in a way that would not match it.

I'll see if I can check/test for configurations like this. Maybe a dedicated task. There may be some simple checks that could be done up-front though. Like pointing out that startingVersion will never be used because it is excluded by your filters. Or noticing when startingVersion is unreasonably later than the latest found tag. For example, if it is a minor or major version ahead of the current latest version tag. This means that it would never be used because we already have a current latest version tag.

It's perhaps not clear that startingVersion isn't always the "starting version", because it's actually "the starting version if there are no other version tags". Which is why I can see why you were tempted to just bump it manually, because it seems reasonable that the plugin would just use that. However the plugin primarily works based on git tags and the startingVersion is basically a fallback typically used only the very first time in a repo without any existing version tags. I think this is also something that could be checked for.

I'm also going to rewrite that error message and maybe add a debug flag to print diagnostic information to make things easier.

JoshMcCullough commented 4 years ago

Our existing tags all start with "v", so don't think they'd be included since we have not configured this to use a prefix. I was also surprised it wasn't picking up the startingVersion.

This is the first "version tag" I'm creating for this repo using this plugin.

I did try removing the entire matching block but was given a different error:

No match found

So I assumed that block was required?

Is it possible that the plugin, even though I have no prefix specified, is still considering my old tags which are prefixed with "v"?

Really appreciate your help!

JoshMcCullough commented 4 years ago

I took a very quick look through the code and it seems like this regex should be updated and/or modified so that it optionally includes the tagPrefix: https://github.com/vivin/gradle-semantic-build-versioning/blob/a1f125286bd776c5060386ba3ab0b388d2ca0972/src/main/groovy/net/vivin/gradle/versioning/VersionUtils.groovy#L24

Note that .*\d++\.\d++\.\d++.* is going to match my "v1.2.3" tag. I was able to fix this by configuring tagPattern as follows:

tagPattern = ~/^\d++\.\d++\.\d++/

Now I get the correct tag when I run:

./gradlew tag -PbumpComponent=minor -PnewPreRelease -Prelease

So a bit of misunderstanding on my part but I'm glad it's working now!

I may suggest that the default tagPattern should start with ^ if there is no tagPrefix, otherwise it should start with ^ followed by the tag prefix and then \d++\.\d++\.\d++. This way, the first time should be much smoother for those who are starting to use this plugin on an existing project.

Thanks again!

vivin commented 4 years ago

Our existing tags all start with "v", so don't think they'd be included since we have not configured this to use a prefix. I was also surprised it wasn't picking up the startingVersion.

The prefix doesn't affect what tags are picked up -- it's just added to the version when making a tag.

I did try removing the entire matching block but was given a different error:

Not Found

That's pretty odd. If the block is not there, it doesn't even consider it. It's hard to tell without knowing the state of your repo and your existing tags.

Note that .\d++.\d++.\d++. is going to match my "v1.2.3" tag. I was able to fix this by configuring tagPattern as follows:

tagPattern = ~/^\d++\.\d++\.\d++/

Yes .*\d++\.\d++\.\d++.* would absolutely match it. This is because we don't want to ignore existing version tags. If you have existing tags that start with v then your tag pattern above basically says that you want to ignore them. Meaning, you don't want to consider existing version tags when determining the new version.

I took a very quick look through the code and it seems like this regex should be updated and/or modified so that it optionally includes the tagPrefix [...] I may suggest that the default tagPattern should start with ^ if there is no tagPrefix, otherwise it should start with ^ followed by the tag prefix and then \d++\.\d++\.\d++.

The reason that VERSION_PATTERN is set as such is so that it matches anything that could include a semantic version. This is basically so that existing tags won't get overlooked when using this plugin.

tagPrefix only controls what prefix is added to the tag when it is made -- it doesn't control the filtering in any way. If the tagPrefix is included in filtering, then you would end up in a situation where you might want to change the prefix, but doing so causes it to not match against existing tags that use a different prefix. This means that you wouldn't be able to determine the new version with respect to the latest existing tag.

This way, the first time should be much smoother for those who are starting to use this plugin on an existing project.

I think the main issue is that I haven't really provided a good explanation as to how this plugin actually does what it does, and how the different options affect that.