[GH-ISSUE #6] Guidance for versionning of pre #5122

Closed
opened 2026-06-15 11:02:45 -05:00 by GiteaMirror · 11 comments
Owner

Originally created by @serialseb on GitHub (Dec 12, 2011).
Original GitHub issue: https://github.com/semver/semver/issues/6

It is often the case that packages contain breaking changes between, say, a beta 1 and beta 2 build. In the wild, a lot of packages seem to want to achieve their release with a clean "2.0.0" version. As API incompatibilities usually happen between those phases, my understanding of the specification is that the version number should be bumped, which means that you couldn't make breaking changes between beta1 and beta2 without bumping the major version.

So in the wild I've seen people use the pre to version their pre-release, aka 1.0.0-public.beta.1 < 1.0.0-public.beta.2. This introduces issues when releasing packages in-between the two, as there is no version number change the dependency on one version or the other cannot be taken from the package manager.

Another issue is that there may be interemdiary builds between beta 1 and beta 2, and it's unclear how one would go about doing this while preserving the correct order of packages. One could try 1.0.0-ci.25 but that would put any ci build as before any of the beta packages, so it seems to me not bumping the version really causes issues there too.

As far as implementing a package manager that can take dependencies, the specification defines what packages match a dependency (aka 1.0.0+build and 1.0.0-alpha both match a 1.0.0 specification) but does not discuss (allowing or disallowing) how dependency on specific builds or pre versions ought to function, if at all.

In other words, the use of pre tags seems to me to be missing guidance on the following points:

  • when should version be bumped between two pre packages
  • explicitly state that the order is forward only and it is expected that any future build sharing a version number can only have alpha builds, then beta builds, etc
  • discussing how package managers ought to implement dependency declarations (only on version, on version+build, on version-alpha+build?), which i'd suggest should be forbidden on builds and optional on pre (so one could take a dependency on beta.1 instead of just on the version, provided you don't make bumping version numbers mandatory between pre builds)
Originally created by @serialseb on GitHub (Dec 12, 2011). Original GitHub issue: https://github.com/semver/semver/issues/6 It is often the case that packages contain breaking changes between, say, a beta 1 and beta 2 build. In the wild, a lot of packages seem to want to achieve their release with a clean "2.0.0" version. As API incompatibilities usually happen between those phases, my understanding of the specification is that the version number should be bumped, which means that you couldn't make breaking changes between beta1 and beta2 without bumping the major version. So in the wild I've seen people use the pre to version their pre-release, aka `1.0.0-public.beta.1 < 1.0.0-public.beta.2`. This introduces issues when releasing packages in-between the two, as there is no version number change the dependency on one version or the other cannot be taken from the package manager. Another issue is that there may be interemdiary builds between beta 1 and beta 2, and it's unclear how one would go about doing this while preserving the correct order of packages. One could try `1.0.0-ci.25` but that would put any ci build as before any of the beta packages, so it seems to me not bumping the version really causes issues there too. As far as implementing a package manager that can take dependencies, the specification defines what packages match a dependency (aka 1.0.0+build and 1.0.0-alpha both match a 1.0.0 specification) but does not discuss (allowing or disallowing) how dependency on specific builds or pre versions ought to function, if at all. In other words, the use of pre tags seems to me to be missing guidance on the following points: - when should version be bumped between two pre packages - explicitly state that the order is forward only and it is expected that any future build sharing a version number can only have alpha builds, then beta builds, etc - discussing how package managers ought to implement dependency declarations (only on version, on version+build, on version-alpha+build?), which i'd suggest should be forbidden on builds and optional on pre (so one could take a dependency on beta.1 instead of just on the version, provided you don't make bumping version numbers mandatory between pre builds)
Author
Owner

@xavierdecoster commented on GitHub (Jan 3, 2012):

This is the way I understand SemVer..

  • As soon as there is a breaking change, whether prerelease version or not, a major version increment seems required.
  • As long as there is no v1.0.0 out there (so not a single actual release exists), no major version increment is required.
  • As soon as a v1.0.0 exists, there can only be one major version increment indicating breaking changes between v1.0.0 and the next non-prerelease version.

This would mean that the first breaking prerelease would increment the major version, and all next breaking changes before the next non-prerelease would not require a major version bump anymore.

Is my understanding correct?

<!-- gh-comment-id:3340901 --> @xavierdecoster commented on GitHub (Jan 3, 2012): This is the way I understand SemVer.. - As soon as there is a breaking change, whether prerelease version or not, a major version increment seems required. - As long as there is no v1.0.0 out there (so not a single actual release exists), no major version increment is required. - As soon as a v1.0.0 exists, there can only be one major version increment indicating breaking changes between v1.0.0 and the next non-prerelease version. This would mean that the first breaking prerelease would increment the major version, and all next breaking changes before the next non-prerelease would not require a major version bump anymore. Is my understanding correct?
Author
Owner

@serialseb commented on GitHub (Jan 3, 2012):

Well that's where we'd be in an absolutely absurd situation. When you start work on a 2.0 release that breaks a 1.0 release and do a beta 1, I do not see any logic in updating to 3.0 for a beta 2, that makes having pre completely useless. OTHA not bumping any version number prevents people from taking dependencies on specific versions (aka specifically beta 1) which will break people more than they need, as beta cycles can be long with some projects (and that is not something I expect the semver spec to try and address either).

<!-- gh-comment-id:3340972 --> @serialseb commented on GitHub (Jan 3, 2012): Well that's where we'd be in an absolutely absurd situation. When you start work on a 2.0 release that breaks a 1.0 release and do a beta 1, I do not see any logic in updating to 3.0 for a beta 2, that makes having pre completely useless. OTHA not bumping any version number prevents people from taking dependencies on specific versions (aka specifically beta 1) which will break people more than they need, as beta cycles can be long with some projects (and that is not something I expect the semver spec to try and address either).
Author
Owner

@serialseb commented on GitHub (Jan 3, 2012):

On a side-note, before nuget moved to support semver as is, those were the reservations I had about implementing pre in openwrap the way it is designed, and prefered the idea of namespaces you could import (so you could add the alpha, beta, rc and ci namespaces and make the namespace independent from the version, and keep the versioning immutability as is). It does not matter now as this is now a fact of life library devs are gonna start adding, hence what I believe needs to be MUST guidance in the spec.

<!-- gh-comment-id:3341175 --> @serialseb commented on GitHub (Jan 3, 2012): On a side-note, before nuget moved to support semver as is, those were the reservations I had about implementing pre in openwrap the way it is designed, and prefered the idea of namespaces you could import (so you could add the alpha, beta, rc and ci namespaces and make the namespace independent from the version, and keep the versioning immutability as is). It does not matter now as this is now a fact of life library devs are gonna start adding, hence what I believe needs to be MUST guidance in the spec.
Author
Owner

@xavierdecoster commented on GitHub (Jan 3, 2012):

Hmm.. not sure my previous statement was clear enough :)
What I meant:

  • you currently have a v1.0 release out there
  • you start working on vNext, which introduces breaking changes (note: vNext, not v2.0, the breaking change is not there yet)
  • a breaking change is introduced: this means incrementing major version and results in v2.0
  • you want to have a beta 1 prerelease, which results in v2.0.0-beta1
  • if beta two introduces additional breaking changes to v2.0.0-beta1, you'd end up with v2.0.0-beta2
  • any future prerelease versions of v2.0.0-x, whether breaking or not, stay on v2.0.0-x, with only an increment of the prerelease tag

Seems OK to me:

  • major version increment indicates breaking change between the non-prerelease versions
  • only the first breaking prerelease version increments major version from v1.0 to v2.0.0-x
  • any subsequent breaking prerelease versions no longer increment the major version, as the breaking change already is indicated towards the next non-prerelease version
<!-- gh-comment-id:3341256 --> @xavierdecoster commented on GitHub (Jan 3, 2012): Hmm.. not sure my previous statement was clear enough :) What I meant: - you currently have a v1.0 release out there - you start working on vNext, which introduces breaking changes (note: vNext, not v2.0, the breaking change is not there yet) - a breaking change is introduced: this means incrementing major version and results in v2.0 - you want to have a beta 1 prerelease, which results in v2.0.0-beta1 - if beta two introduces additional breaking changes to v2.0.0-beta1, you'd end up with v2.0.0-beta2 - any future prerelease versions of v2.0.0-x, whether breaking or not, stay on v2.0.0-x, with only an increment of the prerelease tag Seems OK to me: - major version increment indicates breaking change between the non-prerelease versions - only the first breaking prerelease version increments major version from v1.0 to v2.0.0-x - any subsequent breaking prerelease versions no longer increment the major version, as the breaking change already is indicated towards the next non-prerelease version
Author
Owner

@serialseb commented on GitHub (Jan 3, 2012):

Doesn't seem ok to me based on how people are using beta cycles out there. The nhibernate 2 cycle was very interesting in that respect due to the changes that rippled down on fluent nhibernate. Some packages were built for beta1, and broke for beta 2 when the API changed and things evolved. API breakage between beta 1 and beta 2 is a common occurence.

Dependencies are understood to be taken on the version number, not on build / pre. One could say that we could update package managers to let you depend on a specific beta or above (using the method provided here), and on builds, which would solve the problem for those package managers that would let you do that

As the spec doesn't mention the problem of dependency taking (and I assume it is because it's always been understood that such dependencies only happen on those three components that really are part of the version), I can only assume that it is not expected for dependencies between packages to reference a build or a pre.

The idea that "one should not introduce breaking changes between two published beta packages without incrementing major" would be ludicrous, for it wouldn't solve the problem of breaking dependency trees. "Public" releases is a very relative term as internet-public is not the same as corporate or team-public.

The only way out of there for me is that in the case where packages are pre packages and breaking changes are introduced, the revision number MUST be updated so as to not break package dependencies. Either that or have a normative section (SHOULDs so one can claim full semver compliance or not) to allow taking dependencies in packages against pre tags.

Either way, as it stands the spec is mute on this and this is going to cause issues very very quickly, at least in the current state of the .nettters out there.

<!-- gh-comment-id:3341701 --> @serialseb commented on GitHub (Jan 3, 2012): Doesn't seem ok to me based on how people are using beta cycles out there. The nhibernate 2 cycle was very interesting in that respect due to the changes that rippled down on fluent nhibernate. Some packages were built for beta1, and broke for beta 2 when the API changed and things evolved. API breakage between beta 1 and beta 2 is a common occurence. Dependencies are understood to be taken on the version number, not on build / pre. One could say that we could update package managers to let you depend on a specific beta or above (using the method provided here), and on builds, which would solve the problem for those package managers that would let you do that As the spec doesn't mention the problem of dependency taking (and I assume it is because it's always been understood that such dependencies only happen on those three components that really are part of the version), I can only assume that it is not expected for dependencies between packages to reference a build or a pre. The idea that "one should not introduce breaking changes between two published beta packages without incrementing major" would be ludicrous, for it wouldn't solve the problem of breaking dependency trees. "Public" releases is a very relative term as internet-public is not the same as corporate or team-public. The only way out of there for me is that in the case where packages are pre packages and breaking changes are introduced, the revision number MUST be updated so as to not break package dependencies. Either that or have a normative section (SHOULDs so one can claim full semver compliance or not) to allow taking dependencies in packages against pre tags. Either way, as it stands the spec is mute on this and this is going to cause issues very very quickly, at least in the current state of the .nettters out there.
Author
Owner

@benhamill commented on GitHub (Jan 25, 2012):

I would say, if your dependency declaration tool doesn't allow you to specify anything past the patch number, and you declare a dependency against a version that only has a prerelease version out, then you are taking your library's life in your own hands: You are declaring a dependency on a package that has not officially been released. I don't know if SemVer should actually address that or not, honestly. Part of me thinks that's all on you for trusting something that has declared itself to be volatile.

<!-- gh-comment-id:3646645 --> @benhamill commented on GitHub (Jan 25, 2012): I would say, if your dependency declaration tool doesn't allow you to specify anything past the patch number, and you declare a dependency against a version that only has a prerelease version out, then you are taking your library's life in your own hands: You are declaring a dependency on a package that has _not officially been released_. I don't know if SemVer should actually address that or not, honestly. Part of me thinks that's all on you for trusting something that has declared itself to be volatile.
Author
Owner

@serialseb commented on GitHub (Jan 31, 2012):

I don't think that quite fits with the realities of upgrading from a beta to another. If you prevent people from declaring their actual dependencies because semver suggests that having a beta.1 and beta.2 tag is enough (without the version bump), without semver either suggesting package managers should be able to lock on one or the other version or enforcing the version number change between breaking changes of beta packages, then you're getting package builders to version in a way that's going to break users. It just doesn't feel quite right.

<!-- gh-comment-id:3745054 --> @serialseb commented on GitHub (Jan 31, 2012): I don't think that quite fits with the realities of upgrading from a beta to another. If you prevent people from declaring their actual dependencies because semver suggests that having a beta.1 and beta.2 tag is enough (without the version bump), without semver either suggesting package managers should be able to lock on one or the other version or enforcing the version number change between breaking changes of beta packages, then you're getting package builders to version in a way that's going to break users. It just doesn't feel quite right.
Author
Owner

@haacked commented on GitHub (Feb 10, 2012):

If I understand you correctly, you're concerned about the stability of one beta release to another causing breaks? Isn't that the whole point of the prerelease part though - to tell you that you're taking a big risk by depending on on that release and you're better off depending on a stable release if that doesn't work for you?

If beta1 -> beta2 has huge breaking changes, it seems to me it shouldn't have been called beta in the first place. Perhaps alpha1 and alpha2 would've been better. But I don't think that's encoded in semver specifically. It's just one of those conventions that we should simply agree on.

We'll never get every project to agree on semantics exactly, but hopefully we can set a general consensus on version semantics for those who do buy into SemVer.

<!-- gh-comment-id:3900809 --> @haacked commented on GitHub (Feb 10, 2012): If I understand you correctly, you're concerned about the stability of one beta release to another causing breaks? Isn't that the whole point of the prerelease part though - to tell you that you're taking a big risk by depending on on that release and you're better off depending on a stable release if that doesn't work for you? If beta1 -> beta2 has huge breaking changes, it seems to me it shouldn't have been called beta in the first place. Perhaps alpha1 and alpha2 would've been better. But I don't think that's encoded in semver specifically. It's just one of those conventions that we should simply agree on. We'll never get every project to agree on semantics exactly, but hopefully we can set a general consensus on version semantics for those who do buy into SemVer.
Author
Owner

@haacked commented on GitHub (Dec 20, 2012):

Going to close this one as I don't see us providing explicit definitions to pre-release strings. If we think guidance is necessary, I think it should be recommendations outside of this spec.

<!-- gh-comment-id:11556197 --> @haacked commented on GitHub (Dec 20, 2012): Going to close this one as I don't see us providing explicit definitions to pre-release strings. If we think guidance is necessary, I think it should be recommendations outside of this spec.
Author
Owner

@trusktr commented on GitHub (May 10, 2021):

Maybe X.X.X-beta.N should be treated similarly to 0.0.N where ^X.X.X-beta.N would not match anything higher than beta.N (i.e. no beta.N+1), just as ^0.0.3 would not match 0.0.4.

This would prevent the main issue, which I think is that relying on a common range like ^X.X.X-beta.1 could break an app when tooling automatically installs X.X.X-beta.2 that has breaking change.

I do think "alpha" is a better word to indicate more likelihood of breaking changes though.

<!-- gh-comment-id:836243233 --> @trusktr commented on GitHub (May 10, 2021): Maybe `X.X.X-beta.N` should be treated similarly to `0.0.N` where `^X.X.X-beta.N` would not match anything higher than `beta.N` (i.e. no `beta.N+1`), just as `^0.0.3` would not match `0.0.4`. This would prevent the main issue, which I think is that relying on a common range like `^X.X.X-beta.1` could break an app when tooling automatically installs `X.X.X-beta.2` that has breaking change. I do think "alpha" is a better word to indicate more likelihood of breaking changes though.
Author
Owner

@ljharb commented on GitHub (May 10, 2021):

The semver spec does not contain anything about ranges (pending #584).

The word used can be anything you want - it can be 1.2.3-finalreleasedversion.0 and the semantics would be unchanged.

<!-- gh-comment-id:837147381 --> @ljharb commented on GitHub (May 10, 2021): The semver spec does not contain anything about ranges (pending #584). The word used can be anything you want - it can be `1.2.3-finalreleasedversion.0` and the semantics would be unchanged.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#5122