muratgozel / node-calver

Calendar based software versioning library as node.js module and with cli support. 📅
MIT License
29 stars 5 forks source link

Level 2 semantic tags are incremented incorrectly for pre-releases #21

Closed imgrant closed 6 months ago

imgrant commented 1 year ago

Hello!

I'm using another Node.js package which leverages this great package to do calendar versioning. I couldn't get it to act like I expected in some cases, and I think this is an oversight in how semantic tags are incremented when (pre-release) modifiers are included.

It centres around whether versions with modifier tags should be considered pre-releases or not, i.e. is 2023.6.0 > 2023.6.0-rc.*? To be fair, I can see the argument for modifiers like dev or alpha being considered as 'post-release' (2023.6.0-dev.* > 2023.6.0), but rc ("release candidate") should definitely be considered as a pre-cursor release to the main unsuffixed version; this is how semantic versioning treats pre-release tags.

Edit: a suggested fix is in PR #22

Here's some examples to illustrate:

💡 N.b. date now in the following is June 2023

Incrementing a pre-release

Welcome to Node.js v18.14.2.
Type ".help" for more information.
> c = require('calver')
Calver {
  seperator: '.',
  levels: [
    'CALENDAR', 'MAJOR',
    'MINOR',    'PATCH',
    'DEV',      'ALPHA',
    'BETA',     'RC'
  ],
  _useLocalTime: false
}
> c.inc('YYYY.MM.MINOR', '2023.5.26', 'calendar.minor.rc')
'2023.6.0-rc.0' ✅ 
> c.inc('YYYY.MM.MINOR', '2023.6.0-rc.0', 'calendar.minor.rc')
'2023.6.1-rc.1' ❌ 

My expectation here is that the second example should result in 2023.6.**0**-rc.1, i.e. the semantic MINOR tag should not be incremented.

Going from release to pre-release

Using calendar.rc is a workaround to the former case, to avoid incrementing the minor as well as the rc tag, but when going from release (no modifier tag) to pre-release (adding -rc.0), minor is also needed, in order to increment the minor semantic tag in the case where the date has not changed, i.e. when adding a pre-release modifier tag, the semantic MINOR tag should be incremented (or reset, if the date has changed):

> c.inc('YYYY.MM.MINOR', '2023.5.17', 'calendar.rc')
'2023.6.0-rc.0' ✅ 
> c.inc('YYYY.MM.MINOR', '2023.6.0', 'calendar.rc')
'2023.6.0-rc.0 ❌
> c.inc('YYYY.MM.MINOR', '2023.5.17', 'calendar.minor.rc')
'2023.6.0-rc.0' ✅ 
> c.inc('YYYY.MM.MINOR', '2023.6.0', 'calendar.minor.rc')
'2023.6.1-rc.0 ✅ 

N.b. obviously the result for calendar.rc when the date has not changed is technically correct, since the minor increment was omitted, but my point is that more that it's the 'undesired' result.

Going from pre-release to release

> c.inc('YYYY.MM.MINOR', '2023.6.0-rc.0', 'calendar.minor')
'2023.6.1' ❌ 

Similarly, the expected result here is 2023.6.0, incrementing the pre-release 2023.6.0-rc.0 by calendar.minor (i.e. dropping the modifier tag) should also not increment the minor semantic tag, because the main release 2023.6.0 is newer than its -rc.* pre-releases. Using just calendar as the increment level is not a practical workaround, since that doesn't work when the date has changed:

> c.inc('YYYY.MM.MINOR', '2023.5.17-rc.0', 'calendar')
'2023.5.17' ❌ 
> c.inc('YYYY.MM.MINOR', '2023.5.17-rc.0', 'calendar.minor')
'2023.6.0' ✅  

N.b. this is possibly another/different bug? I would have expected calendar to work here, since the date has changed. It seems to neither reset the minor tag nor update the calendar tag.