gulp-bump icon indicating copy to clipboard operation
gulp-bump copied to clipboard

Prerelease bump not working in conjunction with NuGet

Open NightOwl888 opened this issue 9 years ago • 16 comments

Great library.

I am having some issues interoperating with NuGet because NuGet expects the pre-release format to be something like.

1.2.3-alpha00003
1.5.9-beta00005
2.8.7-RC1

According to SemVer these are supposed to be supported.

A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.

But there is a twist with using them in NuGet - you cannot put a . in the pre-release part of the version. I found that you have a preid option that allows you to specify "alpha", etc. but there doesn't seem to be any way to remove the period after the identifier. I guess NuGet is leveraging the fact that the part after the period is optional and the identifier must be alphanumeric (meaning it can contain a version number).

It is also a NuGet convention to pad the number with leading zeros so the version comparison logic works right. Otherwise 1.0.0-alpha9 will be a higher version than 1.0.0-alpha10.

There also seems to be an issue with the way you implemented the preid - if it is not supplied to the command, but it does exist in the .json file it will be removed instead of bumping the version. But according to the spec it is required during pre-release, so this logic is invalid.

It would be nice if you could fix this. Fortunately other than the pre-release stage it works great. Thanks.

NightOwl888 avatar Jun 08 '15 19:06 NightOwl888

Thanks!

The quote you copied does seem to identify that the identifier is dot separated, must not have leading zeros (against the NuGet style) and has examples for the supported format:

Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version .... Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

If you have a version 1.2.0-alpha.12.4 and you give it a semver patch (the default in gulp-bump) it will (internally, and by design) patch the version from 1.2.0-alpha.12.4 to 1.2.1 as a patch is in a completely different version hierarchy.

To confirm this with pure semver:


var semver = require('semver');

var version = '1.2.0';

var prerelease = semver.inc(version, 'prerelease', 'testAlpha');

console.log(prerelease);  // 1.2.1-testAlpha.0

var prerelease = semver.inc(prerelease, 'prerelease');

console.log(prerelease); // 1.2.1-testAlpha.1

var patchOver = semver.inc(prerelease, 'patch');

console.log(patchOver); // 1.2.1

stephenlacy avatar Jun 10 '15 04:06 stephenlacy

Thanks for the prompt reply.

As I pointed out, the NuGet versioning scheme does follow the SemVer requirements by taking advantage of putting the number as part of the alphanumeric preid identifier. The difference is that there is no . in the scheme because that would effectively make it a 4 digit .NET identifier (which is the scheme Microsoft has always used), and would end up rejecting the pre-release id when trying to build the NuGet package on the NuGet.exe CLI. The expert recommendation for NuGet is to NOT use the (optional) 4th part of the scheme and to make it part of the pried in order to make a SemVer compliant number that also works with Microsoft's (much older) 4 part scheme. See number 2 and 3 in that document. Also, see Hijacking the Pre-Release Tag for the reason why the zero padding is required in this case. That document also explains why this scheme is the only common ground available for SemVer compliant versioning with NuGet. In other words the pre-release format used by gulp-bump is not supported.

Note that there are also examples of this versioning scheme (which again is SemVer compliant) on the git tag documentation.

The problem is that there doesn't seem to be a way to configure gulp-bump to increment the pre-release number with this scheme. I am able to work around it by passing the version from the CI server into the version parameter, but it would be nice if there were a way to change the format of the number to support this (SemVer compliant) scheme so pre-releases can be bumped from the command line.

As a feature request, I would suggest to add a pre-release format string as an option that would default to your current scheme, but be changeable to other schemes (and understand how to pad with leading zeros, or alternatively just default to a zero-padded 5-digit number to cover the worst case scenario when not separated from the preid with a .).

// Default pre-release format string
"#version#-#preid#.#revision#"

// Custom pre-release format string padded to 5 places
"#version#-#pried##revision-pad5#"

Another (much simpler) way might be to just have a Boolean argument that specifies whether or not to include the final ., and automatically pad the number to 5 digits if it is part of the preid. This is probably more in line with your thinking as I don't think there are any other pre-release format options that are SemVer compliant.

NightOwl888 avatar Jun 10 '15 10:06 NightOwl888

Bumping this to check update. :) With asp.net 5 now in rc1, I am in desperate need for automatically bumping my version numbers. Will nuget versioning scheme be supported by gulp-bump?

+1 for @NightOwl888 suggestion.

ankitbko avatar Nov 22 '15 09:11 ankitbko

If semver supports it then I will add it.

stephenlacy avatar Nov 23 '15 17:11 stephenlacy

@stevelacy

I stand by my original reply. The NuGet version scheme _is_ SemVer compliant. I have already included links to the relevant documentation and 2 potential solutions to solve this.

And as @ankitbko pointed out, the demand for this is about to go up drastically now that ASP.NET 5 will be supporting project.json configuration files as soon as its released (Q1 2016). I was able to work around this because I use a CI server that provides the version number to gulp-bump, but others might not be so lucky with their workflow.

NightOwl888 avatar Nov 24 '15 01:11 NightOwl888

@NightOwl888 I found a way to increase pre-release build using DNX_BUILD_VERSION environment variable. @stevelacy However I would still like the feature included into gulp-bump, as we are using this to bump other versions, might as well use it to bump pre-release

ankitbko avatar Nov 24 '15 07:11 ankitbko

@ankitbko - Thanks for the info. It doesn't apply to my project because I am using gulp-bump in a build script for a jQuery plugin to be released by NuGet, NPM, Bower, and CDN. But I am sure posting the information about DNX_BUILD_VERSION here will help someone.

NightOwl888 avatar Nov 24 '15 08:11 NightOwl888

@NightOwl888 I would love to support all possible versioning specs. I have looked into http://npm.im/semver code and have not found any support for a non dot separator for preids. As this line shows: https://github.com/npm/node-semver/blob/master/semver.js#L75

As the semver.org spec outlines:

A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

Padding is not valid as per the spec. The only other line regarding another separator:

Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata SHOULD be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85.

If they supported it, then what is currently added should work https://github.com/stevelacy/gulp-bump/blob/master/index.js#L83 with probably an option for the separator.

I only could see the git tag example as an example for a non dot (.) or plus (+) separated pre-release version number. I looked for nuget versioning and did find this: https://nuget.codeplex.com/SourceControl/network/forks/mkchandler/nuget/contribution/5599 I would prefer if nuget would fully follow the current 2.0.0 semver spec - as they have migrated to github the PR and issues have faded.


As such any changes to gulp-bump is no longer following semver; I am not opposed to that provided I am not creating my own tokenizer (forking semver) for determining and bumping the a numerical value following a hyphen (regex).

stephenlacy avatar Nov 25 '15 05:11 stephenlacy

NuGet _does not use_ any dot-separated pre-release version identifiers (which I agree may not contain any zero padded numbers). The NuGet pack command will fail if it encounters one.

Pre-release Version

Hyphen, followed by one or more dot-separated pre-release version identifiers.

Per the NuGet documentation:

including the SemVer-compatible build number with dot notation is not allowed: 1.0.1-build.23

NuGet is taking advantage of the fact that a non-numeric identifier can end with numbers:

Non-numeric Identifier

Zero or more digits, followed by a letter or hyphen, and then zero or more letters, digits, or hyphens.

src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*';

A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

Since this is the slot they are putting the numbers into, they can be padded with zeros. The Non-Numeric Identifier spec supports [0-9], so there is absolutely nothing wrong with this. The reason for the padding is because NuGet uses lexicographic ASCII sort order when comparing pre-release version numbers, and since we don't always know how many versions we will have in advance it is safer to pad with 3-5 digits total (or allow the user to be able to specify the number of digits) to ensure the versions are always compared properly.

As I mentioned in my original post, there are typically no additional hyphens (and definitely no periods) in the NuGet supported format. Ideally, gulp-bump would have an option to bump the numeric portion of the format. Therefore, a bump for each of these pre-release numbers:

1.2.3-alpha00003
1.5.9-beta00005
2.8.7-RC1

Should result in the following:

1.2.3-alpha00004
1.5.9-beta00006
2.8.7-RC2

As for the reasoning why NuGet does this - I am guessing it is because they are merging the version number with the traditional 4-segment numbers that Microsoft has used for at least 25 years (Major.Minor.Build.Revision).

You are welcome to contact the NuGet team to see if getting them to support numeric identifiers is a possibility. However, keep in mind that NuGet has been around for 5 years - so even if it is possible to get them to change this, there is still the matter of supporting the existing NuGet versions.

As such any changes to gulp-bump is no longer following semver; I am not opposed to that provided I am not creating my own tokenizer (forking semver) for determining and bumping the a numerical value following a hyphen (regex).

The NuGet versioning scheme is still SemVer compliant. So, the semver validation will still work. There just needs to be a way to parse and then increment the version number in the preid, and then return the new preid with the rest of the version. That could potentially be done with a regex replace. This could be done without calling semver.inc, since in this case we wouldn't be incrementing anything that semver is aware of.

Alternatively, parse the number out of the string and convert it to the existing . format, call semver.inc, determine the number of characters after the last ., work out how many zeros to pad with, and then replace the last . with the zeros.

// Version from file
1.0.1-build00022

// Parsed to semver number

1.0.1-build.22

// After call to semver.inc

1.0.1-build.23

// We have 2 digits after the .
// so we need 3 padded 0's to total 5 places.

1.0.1-build00023

It would seem that this needs to be a special case, so it would be reasonable to add some kind of option to specify as NuGet version scheme.

NightOwl888 avatar Nov 25 '15 08:11 NightOwl888

I agree with @NightOwl888. Nuget is SemVer compliant. If you are still worried, adding this as an option will not really break the underlying concept of gulp-bump.

ankitbko avatar Nov 25 '15 18:11 ankitbko

Rather busy, haven't gotten around to adding the option. Anyone up for it? https://github.com/stevelacy/gulp-bump/issues/40#issuecomment-160850882

stephenlacy avatar Dec 01 '15 04:12 stephenlacy

Was hoping gulp-bump would solve my ASPNET 5 NuGet versioning hell.

No joy it seems :-(

shederman avatar Jan 28 '16 12:01 shederman

PR?

stephenlacy avatar Jan 28 '16 17:01 stephenlacy

I would love to, but unfortunately time pressures are forcing me down the road of the quick rather than the good.

Given up on marking the packages as pre-release with a build number, and just saying everything is release, even when it's not.

Will try to come back to it later if I have time

On Thu, 28 Jan 2016 at 7:05 PM, Steve Lacy [email protected] wrote:

PR?

— Reply to this email directly or view it on GitHub https://github.com/stevelacy/gulp-bump/issues/39#issuecomment-176285069.

shederman avatar Jan 28 '16 18:01 shederman

I submitted a PR to NuGet to see if they would conform to SemVer. https://github.com/NuGet/NuGet2/pull/45

BertCotton avatar Apr 04 '16 21:04 BertCotton

@BertCotton excellent!

stephenlacy avatar Apr 04 '16 22:04 stephenlacy