[GH-ISSUE #200] Nightly builds not supported #5252

Closed
opened 2026-06-15 11:24:43 -05:00 by GiteaMirror · 96 comments
Owner

Originally created by @mearns on GitHub (May 20, 2014).
Original GitHub issue: https://github.com/semver/semver/issues/200

I really like semver except for specification that all strings following the Major.minor.patch version number indicate a pre-release. I feel that this is inconvenient for, if not incompatible with, rapid development environments with development builds (e.g., nightly snapshot builds).

In my team, we do not always know what the version number of the next release will be, because we don't know what kind of changes will be ready for inclusion when it is time to release. We therefore do not bump the version number until the release. Instead, we add a "post-release" suffix to the version string immediately after the release. For instance, we release version 1.0.0, and then add the string "-dev" to the version string, so that until the next release, we are all working with version 1.0.0-dev. Nightly builds will include this suffix on the version string, indicating that it is a development build.

Conceptually, it is very similar to the idea of a pre-release identifier as you've described it, but the important difference is that its precedence is higher than the version number it attaches to. Again, this is because we don't know if the next release is going to 1.0.1 with a critical bug fix the next day, or 1.1.0 with new features sometime next month.

I would love to see semver updated to support such a feature, though I'm not sure how exactly it could be incorporated without breaking backward compatibility. Perhaps this could be worked into semver ver 3.0, unless you have a suggestion for how semver can handle nightly builds.

Originally created by @mearns on GitHub (May 20, 2014). Original GitHub issue: https://github.com/semver/semver/issues/200 I really like semver except for specification that all strings following the Major.minor.patch version number indicate a pre-release. I feel that this is inconvenient for, if not incompatible with, rapid development environments with development builds (e.g., nightly snapshot builds). In my team, we do not always know what the version number of the next release will be, because we don't know what kind of changes will be ready for inclusion when it is time to release. We therefore do not bump the version number until the release. Instead, we add a "post-release" suffix to the version string immediately after the release. For instance, we release version 1.0.0, and then add the string "-dev" to the version string, so that until the next release, we are all working with version 1.0.0-dev. Nightly builds will include this suffix on the version string, indicating that it is a development build. Conceptually, it is very similar to the idea of a pre-release identifier as you've described it, but the important difference is that its precedence is _higher_ than the version number it attaches to. Again, this is because we don't know if the next release is going to 1.0.1 with a critical bug fix the next day, or 1.1.0 with new features sometime next month. I would love to see semver updated to support such a feature, though I'm not sure how exactly it could be incorporated without breaking backward compatibility. Perhaps this could be worked into semver ver 3.0, unless you have a suggestion for how semver can handle nightly builds.
GiteaMirror added the consensus seekingquestion labels 2026-06-15 11:24:43 -05:00
Author
Owner

@crazedsanity commented on GitHub (May 20, 2014):

Build metadata is part of the specification. If you look at version 2.0.0 of the spec [ http://semver.org/spec/v2.0.0.html ], build metadata is added to a version number with a plus sign. So your version number for "dev" would be 1.0.0+dev instead of 1.0.0-dev.

<!-- gh-comment-id:43650626 --> @crazedsanity commented on GitHub (May 20, 2014): Build metadata is part of the specification. If you look at version 2.0.0 of the spec [ http://semver.org/spec/v2.0.0.html ], build metadata is added to a version number with a plus sign. So your version number for "dev" would be `1.0.0+dev` instead of `1.0.0-dev`.
Author
Owner

@crazedsanity commented on GitHub (May 20, 2014):

FYI, that's from item 10 in the spec. Important to note, from the spec: "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."

<!-- gh-comment-id:43650911 --> @crazedsanity commented on GitHub (May 20, 2014): FYI, that's from item 10 in the spec. Important to note, from the spec: "`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.`"
Author
Owner

@mearns commented on GitHub (May 20, 2014):

Thanks, but I would not consider this meta data. Specifically, the semver spec says that metadata cannot be considered when deciding precedence, thus the nightly version (e.g. 1.0.0+dev) would be considered the same version as the released version from which it derives (1.0.0).

Really, I think development build tags deserve their own field, distinct from both meta-data and pre-release identifiers. In the above example, a package manager which relies on semver would be unable to update from a released version to a nightly version. While this may be desirable in many cases (since most users will not want to update to development versions), forcing it to be the case defeats the purpose of having development versions, if no one can install them.

On the other hand, if the package manager could identify that the nightly version is more recent than the released version, but that it is in fact a development version, it could provide the user with an option of whether or not they want to install development versions (like being on the firefox beta or aurora channels).

My vote/recommendation for a future version of semver would be to use a different separator for these "post release" identifiers. For instance, instead of just a hyphen, a hyphen followed by a star. Since a star is not part of a valid identifier in the semver spec, there should not be any ambiguity. The question is how existing semver parsers would (and should) handle such a construct.

<!-- gh-comment-id:43663346 --> @mearns commented on GitHub (May 20, 2014): Thanks, but I would not consider this meta data. Specifically, the semver spec says that metadata cannot be considered when deciding precedence, thus the nightly version (e.g. `1.0.0+dev`) would be considered the same version as the released version from which it derives (`1.0.0`). Really, I think development build tags deserve their own field, distinct from both meta-data and pre-release identifiers. In the above example, a package manager which relies on semver would be unable to update from a released version to a nightly version. While this may be desirable in many cases (since most users will not want to update to development versions), forcing it to be the case defeats the purpose of having development versions, if no one can install them. On the other hand, if the package manager could identify that the nightly version is more recent than the released version, but that it is in fact a development version, it could provide the user with an option of whether or not they want to install development versions (like being on the firefox [beta or aurora channels](https://www.mozilla.org/en-US/firefox/channel/#beta)). My vote/recommendation for a future version of semver would be to use a different separator for these "post release" identifiers. For instance, instead of just a hyphen, a hyphen followed by a star. Since a star is not part of a valid identifier in the semver spec, there should not be any ambiguity. The question is how existing semver parsers would (and should) handle such a construct.
Author
Owner

@crazedsanity commented on GitHub (May 20, 2014):

It seems like you're looking for the solution to a very specific problem.

What I would consider is using the actual version number to signify newer "nightly build" versions. So, in the case that you've released version 1.1.0, then your nightly build can show newer than that simply by updating the patch version, and just add the meta data, such as 1.1.0+dev2048. Should a "newer" nightly build be released (e.g. same night), then just update the meta data again, such as 1.1.0+dev2049. Those affected can decide how to handle the changed version for themselves. Or release it as 1.1.1+dev2049, and there would be no question as to whether it was new or not.

<!-- gh-comment-id:43673303 --> @crazedsanity commented on GitHub (May 20, 2014): It seems like you're looking for the solution to a very specific problem. What I would consider is using the actual version number to signify newer "nightly build" versions. So, in the case that you've released version `1.1.0`, then your nightly build can show newer than that simply by updating the patch version, and just add the meta data, such as `1.1.0+dev2048`. Should a "newer" nightly build be released (e.g. same night), then just update the meta data again, such as `1.1.0+dev2049`. Those affected can decide how to handle the changed version for themselves. Or release it as `1.1.1+dev2049`, and there would be no question as to whether it was new or not.
Author
Owner

@crazedsanity commented on GitHub (May 20, 2014):

A lot of the issues I see regarding specialized parsing--as with the meta data--seem to revolve around some want/need to avoid updating the version, and I personally think it's just fine to have frequent changes to the PATCH component. Releasing 1.1.0 and then very soon after releasing 1.1.2 or even 1.1.13 is just fine, I think.

<!-- gh-comment-id:43677321 --> @crazedsanity commented on GitHub (May 20, 2014): A lot of the issues I see regarding specialized parsing--as with the meta data--seem to revolve around some want/need to avoid updating the version, and I personally think it's just fine to have frequent changes to the PATCH component. Releasing `1.1.0` and then very soon after releasing `1.1.2` or even `1.1.13` is just fine, I think.
Author
Owner

@FichteFoll commented on GitHub (May 20, 2014):

I just wanna hop in quickly to discourage from using 1.1.0+dev2048 but rather 1.1.0+dev.2048.

<!-- gh-comment-id:43692252 --> @FichteFoll commented on GitHub (May 20, 2014): I just wanna hop in quickly to discourage from using `1.1.0+dev2048` but rather `1.1.0+dev.2048`.
Author
Owner

@crazedsanity commented on GitHub (May 21, 2014):

@FichteFoll - agreed, I realized my mistake but got distracted before I could fix. Thanks for the clarification. :)

<!-- gh-comment-id:43706957 --> @crazedsanity commented on GitHub (May 21, 2014): @FichteFoll - agreed, I realized my mistake but got distracted before I could fix. Thanks for the clarification. :)
Author
Owner

@FichteFoll commented on GitHub (May 21, 2014):

Anyway, to get back to the actual discussion.

metadata cannot be considered when deciding precedence

Actually, it "SHOULD" not be considered. In my implementation of semver I do consider build metadata when deciding precedence - mainly because this clause didn't exist in 2.0.0-rc.2 - and I'm thinking about keeping it that way for internal reasons and this one here.

So, a good example for allowing this kind of "higher than x" versioning is the usage of gitflow. You don't know the release version until you create the release branch and thus depend on the current develop branch or an arbitrarily increased patch version. The most logical step would be to increase on the current version instead of decreasing on a potential future version.

So, I can think of two options here:

  1. Remove the clause from the spec that discourages from using build metadata for comparisons or rather limit it to only non-Dev (internal) releases.
  2. Just ignore the clause because it's only a "SHOULD".

Edit: Phrasing.

<!-- gh-comment-id:43722207 --> @FichteFoll commented on GitHub (May 21, 2014): Anyway, to get back to the actual discussion. > metadata cannot be considered when deciding precedence Actually, it "SHOULD" not be considered. In [my implementation of semver](https://github.com/FichteFoll/pysemver) I do consider build metadata when deciding precedence - mainly because this clause didn't exist in 2.0.0-rc.2 - and I'm thinking about keeping it that way for internal reasons and this one here. So, a good example for allowing this kind of "higher than x" versioning is the usage of gitflow. You don't know the release version until you create the release branch and thus depend on the current develop branch or an arbitrarily increased patch version. The most logical step would be to increase on the current version instead of decreasing on a potential future version. So, I can think of two options here: 1. Remove the clause from the spec that discourages from using build metadata for comparisons or rather limit it to only non-Dev (internal) releases. 2. Just ignore the clause because it's only a "SHOULD". Edit: Phrasing.
Author
Owner

@mearns commented on GitHub (May 21, 2014):

I disagree that this is a "very specific problem". Nightly and other development builds are extremely common practice.

I'm thinking hard about your suggestion to simply bump the patch number for development builds. On the face of it it seems reasonable, but there's some nagging me about it that I can't quite put my finger on.

<!-- gh-comment-id:43746309 --> @mearns commented on GitHub (May 21, 2014): I disagree that this is a "very specific problem". Nightly and other development builds are extremely common practice. I'm thinking hard about your suggestion to simply bump the patch number for development builds. On the face of it it seems reasonable, but there's some nagging me about it that I can't quite put my finger on.
Author
Owner

@mearns commented on GitHub (May 21, 2014):

Ah, I figured out what is nagging me about using the patch version for development builds: development builds do not necessarily keep the interface intact.

For instance, say I'm starting with version 1.0.0. Now I add a new function to the public interface during development, but am not ready to make an official release. So my nightly build, for instance, should be 1.1.0+dev. It can't be 1.0.1+dev, because that would imply that anything that works with it will also work with 1.0.0: the minor version bump is necessary to indicate the addition to the API.

Before my next release, I decide that I don't want that function after all, and remove it. I now have to release as 2.0.0, because I've removed something from the API relative to the previous release, 1.1.0+dev. Even though 1.0.0 and 2.0.0 have the exact same API, I had to bump the major version, which means existing clients built against 1.0.0 will have to assume that they can't work with the new 2.0.0 version.

It may sound contrived, but in my experience, a fast paced development environment frequently leads to temporary changes to the API as part of the development cycle and as far as I can tell, semver is incompatible with this increasingly common type of development.

<!-- gh-comment-id:43747036 --> @mearns commented on GitHub (May 21, 2014): Ah, I figured out what is nagging me about using the patch version for development builds: development builds do not necessarily keep the interface intact. For instance, say I'm starting with version `1.0.0`. Now I add a new function to the public interface during development, but am not ready to make an official release. So my nightly build, for instance, should be `1.1.0+dev`. It can't be `1.0.1+dev`, because that would imply that anything that works with it will also work with `1.0.0`: the minor version bump is necessary to indicate the addition to the API. Before my next release, I decide that I don't want that function after all, and remove it. I now have to release as `2.0.0`, because I've removed something from the API relative to the previous release, `1.1.0+dev`. Even though `1.0.0` and `2.0.0` have the exact same API, I had to bump the major version, which means existing clients built against `1.0.0` will have to assume that they can't work with the new `2.0.0` version. It may sound contrived, but in my experience, a fast paced development environment frequently leads to temporary changes to the API as part of the development cycle and as far as I can tell, semver is incompatible with this increasingly common type of development.
Author
Owner

@damianpowell commented on GitHub (May 21, 2014):

At my company we take "SHOULD NOT" to mean that we may, if we so choose, consider build meta data for version precedence. To this end, we use it in a similar manner to that which @mearns suggests - that is, 1.0.0+foo will always have higher precedence than 1.0.0. Likewise, 1.0.0+build.24 will have a higher precedence that 1.0.0+build.3.

<!-- gh-comment-id:43747705 --> @damianpowell commented on GitHub (May 21, 2014): At my company we take "SHOULD NOT" to mean that we may, if we so choose, consider build meta data for version precedence. To this end, we use it in a similar manner to that which @mearns suggests - that is, 1.0.0+foo will always have higher precedence than 1.0.0. Likewise, 1.0.0+build.24 will have a higher precedence that 1.0.0+build.3.
Author
Owner

@mearns commented on GitHub (May 21, 2014):

@damianpowell
I'm glad to hear some other people are using a similar development process and have similar needs. However, the problem arises if those development builds are handled by some third party package manager that doesn't treat meta data that way (since the spec allows, and in fact encourages, them to do so).

<!-- gh-comment-id:43749115 --> @mearns commented on GitHub (May 21, 2014): @damianpowell I'm glad to hear some other people are using a similar development process and have similar needs. However, the problem arises if those development builds are handled by some third party package manager that doesn't treat meta data that way (since the spec allows, and in fact encourages, them to do so).
Author
Owner

@crazedsanity commented on GitHub (May 21, 2014):

@FichteFoll raises an interesting point, but those points should be tempered by the light @damianpowell and @mearns brings: encouraging use of nightly builds makes the the build information non-trivial to the process of determining which part of the version string to increment, especially in the instance where a nightly build can introduce temporary breaking changes that are later discarded.

These are all interesting points. I've been pretty "religious" about updating minor versions (in a 0.x version environment) in the situation that a break in the API has been introduced, even though it is later disregarded (which leads to another version bump). In a post-1.0 versioned environment, I can see how such a scheme would easily lead to lots of major version bumps--in my pre-1.0 world, 0.1.0 and 0.2.0 are roughly equivalent in nature to 1.0.0 and 2.0.0.

I'll be watching this one closely, as much of my public libraries are close to or already breached the 1.0 mark.

<!-- gh-comment-id:43758862 --> @crazedsanity commented on GitHub (May 21, 2014): @FichteFoll raises an interesting point, but those points should be tempered by the light @damianpowell and @mearns brings: encouraging use of nightly builds makes the the build information non-trivial to the process of determining which part of the version string to increment, especially in the instance where a nightly build can introduce temporary breaking changes that are later discarded. These are all interesting points. I've been pretty "religious" about updating minor versions (in a 0.x version environment) in the situation that a break in the API has been introduced, even though it is later disregarded (which leads to another version bump). In a post-1.0 versioned environment, I can see how such a scheme would easily lead to lots of major version bumps--in my pre-1.0 world, 0.1.0 and 0.2.0 are roughly equivalent in nature to 1.0.0 and 2.0.0. I'll be watching this one closely, as much of my public libraries are close to or already breached the 1.0 mark.
Author
Owner

@EddieGarmon commented on GitHub (May 21, 2014):

The failure here it seems, is you are trying to force a automated build versioning scheme independent of the semantics of SemVer, and then force it onto SemVer. (as with a lot of other issues recorded here).

IMO, your automated build should either automatically verify the public API changeset, then appropriately increment the version, or accept an input that tells you of major/minor/patch increment.

You cannot safely determine the next version of a public API before making the changes, and false attempts to do so will only lead to heartache.

<!-- gh-comment-id:43763701 --> @EddieGarmon commented on GitHub (May 21, 2014): The failure here it seems, is you are trying to force a automated build versioning scheme independent of the semantics of SemVer, and then force it onto SemVer. (as with a lot of other issues recorded here). IMO, your automated build should either automatically verify the public API changeset, then appropriately increment the version, or accept an input that tells you of major/minor/patch increment. You **cannot** safely determine the next version of a public API before making the changes, and false attempts to do so will only lead to heartache.
Author
Owner

@mearns commented on GitHub (May 22, 2014):

@EddieGarmon
The point of my earlier comment is that during development, it is inappropriate to be bumping version numbers because changes made to the API during development may not be permanent, and you could end up having to bump the major version unnecessarily, which causes heartache for your end users.

You're absolutely right, though: the problem is that we want some additional semantics which SemVer does not provide. Hence opening an issue to request it. My point is that the semantics encapsulated in semver are too limited to support a very common development style, which will restrict adoption of semver. The idea of "extra" versioning information is already present in semver via the pre-release identifiers. All I'm looking for is a similar allowance for "post-release" identifiers to work with development builds, so that semver can be more widely used.

<!-- gh-comment-id:43882597 --> @mearns commented on GitHub (May 22, 2014): @EddieGarmon The point of my earlier comment is that during development, it is inappropriate to be bumping version numbers because changes made to the API during development may not be permanent, and you could end up having to bump the major version unnecessarily, which causes heartache for your end users. You're absolutely right, though: the problem is that we want some additional semantics which SemVer does not provide. Hence opening an issue to request it. My point is that the semantics encapsulated in semver are too limited to support a very common development style, which will restrict adoption of semver. The idea of "extra" versioning information is already present in semver via the pre-release identifiers. All I'm looking for is a similar allowance for "post-release" identifiers to work with development builds, so that semver can be more widely used.
Author
Owner

@EddieGarmon commented on GitHub (May 22, 2014):

There are only ever two kinds of "releases", official - should never change, and "pre" meaning this might be the next step forward. In development, you are always exploring the next possible step forward, aka you are always working on the next 'pre' release. SemVer support these two scenarios perfectly, and if you would shift your thinking from 'I'm building after X', to 'I'm working on the next Y' (using prerelease) then there is no need for what you are asking.

What is missing, in general, are the tools to help all developers properly (and automatically) determine the appropriate and correct version at build time.

<!-- gh-comment-id:43901479 --> @EddieGarmon commented on GitHub (May 22, 2014): There are only ever two kinds of "releases", official - should never change, and "pre" meaning this might be the next step forward. In development, you are always exploring the next possible step forward, aka you are always working on the next 'pre' release. SemVer support these two scenarios perfectly, and if you would shift your thinking from 'I'm building after X', to 'I'm working on the next Y' (using prerelease) then there is no need for what you are asking. What is missing, in general, are the tools to help all developers properly (and automatically) determine the appropriate and correct version at build time.
Author
Owner

@mearns commented on GitHub (May 22, 2014):

@EddieGarmon
No, you're missing the whole point of my argument. In many many cases, you do not know what "next Y" is going to be, because you don't know what changes you're going to include in the next release. It may be only bug fixes, in which case Y is going to be a bump to the patch version number, it could be additions to the interface (minor version is bumped), or it could be a loss of compatibility (major version bump). You said yourself: "You cannot safely determine the next version of a public API before making the changes".

Until you are ready to set in stone exactly what changes are going to be included in the next release, the only sane option is to mark your versions as "post-X", not "pre-Y".

<!-- gh-comment-id:43910004 --> @mearns commented on GitHub (May 22, 2014): @EddieGarmon No, you're missing the whole point of my argument. In many many cases, you do not know what "next Y" is going to be, because you don't know what changes you're going to include in the next release. It may be only bug fixes, in which case Y is going to be a bump to the patch version number, it could be additions to the interface (minor version is bumped), or it could be a loss of compatibility (major version bump). You said yourself: "You cannot safely determine the next version of a public API before making the changes". Until you are ready to set in stone exactly what changes are going to be included in the next release, the only sane option is to mark your versions as "post-X", not "pre-Y".
Author
Owner

@EddieGarmon commented on GitHub (May 22, 2014):

@mearns
I understand your point completely.

Assume I am working on a project that strictly adheres to the current SemVer spec. Today we publish a release the official 1.2.3 build. (Yay!!) Then tomorrow I get a request to make a feature change. Great, time to get to work. So, do I start by setting the version, absolutely not. I get to work and solve the problem. Once I am done, then I inspect the public API delta and let that tell me the next version number to use. It could be any of the following: 1.2.4-dev.1, 1.3.0-dev.1, or 2.0.0-dev.1. (where 'dev' is my current prerelease designation, and the 1 is the next sequential number of currently published builds with the same version and prerelease designation). When I am ready to publish this prerelease package, its version is set for me, all I have to do is tag the generated version in git. If I have a consumer that wants the latest bits, they get the newest bits by specifying the version range of interest and that they want prereleases included.

How does it work in my local development? I always use version 0.0.0 in code as a placeholder. DevEnv builds and UnitTests work fine this way. Only when I execute a 'Publish' task in my build scripts do I swap out the 0.0.0 for the contents of a file like semver.txt

Again, the spec as written supports your scenario, but it appears that your tools do not. Don't change the spec, build the right tools.

<!-- gh-comment-id:43932319 --> @EddieGarmon commented on GitHub (May 22, 2014): @mearns I understand your point completely. Assume I am working on a project that strictly adheres to the current SemVer spec. Today we publish a release the official 1.2.3 build. (Yay!!) Then tomorrow I get a request to make a feature change. Great, time to get to work. So, do I start by setting the version, absolutely not. I get to work and solve the problem. Once I am done, then I inspect the public API delta and let that tell me the next version number to use. It could be any of the following: 1.2.4-dev.1, 1.3.0-dev.1, or 2.0.0-dev.1. (where 'dev' is my current prerelease designation, and the 1 is the next sequential number of currently published builds with the same version and prerelease designation). When I am ready to publish this prerelease package, its version is set for me, all I have to do is tag the generated version in git. If I have a consumer that wants the latest bits, they get the newest bits by specifying the version range of interest and that they want prereleases included. How does it work in my local development? I always use version 0.0.0 in code as a placeholder. DevEnv builds and UnitTests work fine this way. Only when I execute a 'Publish' task in my build scripts do I swap out the 0.0.0 for the contents of a file like [semver.txt](https://github.com/EddieGarmon/GraduatedCylinder/blob/master/Build/Psake/semver.txt) Again, the spec as written supports your scenario, but it appears that your tools do not. Don't change the spec, build the right tools.
Author
Owner

@mearns commented on GitHub (May 23, 2014):

It has nothing to do with tools. Development builds could just as well be built manually.

Continuing with your scenario, lets your change was to add a function to the public interface, you did created version 1.3.0-dev.1. What do you do when management decides they don't want this feature after all. You remove it, and what do you set the version to? To adhere to semver, you need to mark the version number as 2.0.0 (or 2.0.0-dev.1, for instance), because you removed something from the public API. If you mark it as 1.4.0, for instance, then any one who was getting a jump start and coding against the 1.3.0 dev release will justifiably assume that their code is compatible with 1.4.0, but it's not, because you removed that new API function that they were so excited about. So as far as I can tell, you have no choice within semver but to bump the major version number.

My argument is that this is garbage. Version 2.0.0 and version 1.2.3 have the exact same public interface, but you had to bump the major version number because semver doesn't account for this properly. Bumping the major version sucks because now everyone has to assume that none of their existing code is compatible with your new version: their existing plugins, clients, add-ons, or whatever, are all going to stop working, even though they actually are compatible, and the only reason they've been marked incompatible is because semver doesn't support this increasingly common development style.

<!-- gh-comment-id:44003035 --> @mearns commented on GitHub (May 23, 2014): It has nothing to do with tools. Development builds could just as well be built manually. Continuing with your scenario, lets your change was to add a function to the public interface, you did created version 1.3.0-dev.1. What do you do when management decides they don't want this feature after all. You remove it, and what do you set the version to? To adhere to semver, you need to mark the version number as 2.0.0 (or 2.0.0-dev.1, for instance), because you removed something from the public API. If you mark it as 1.4.0, for instance, then any one who was getting a jump start and coding against the 1.3.0 dev release will justifiably assume that their code is compatible with 1.4.0, but it's not, because you removed that new API function that they were so excited about. So as far as I can tell, you have no choice within semver but to bump the major version number. My argument is that this is garbage. Version 2.0.0 and version 1.2.3 have the exact same public interface, but you had to bump the major version number because semver doesn't account for this properly. Bumping the major version sucks because now everyone has to assume that none of their existing code is compatible with your new version: their existing plugins, clients, add-ons, or whatever, are all going to stop working, even though they actually are compatible, and the only reason they've been marked incompatible is because semver doesn't support this increasingly common development style.
Author
Owner

@zafarkhaja commented on GitHub (May 23, 2014):

@mearns, I think your problem is not the problem SemVer is trying to solve. If you carefully read the introduction part of the specification you'll see that the main problem addressed by SemVer is the "dependency hell", and it's more about backward compatibility of APIs than anything else.

What could help you, though, is a different approach to the development process and/or release management. Try a workflow similar to A successful Git branching model.

A few points to note:

  1. You have to bump a version only if it's a public release. You don't need to bump versions of development and nightly builds because they're not public and are subject to change. But, you can append a build version to the current normal version.
  2. Using feature branches and a separate release branch will definitely let you know if the coming release breaks the backward compatibility of your API.
  3. Versioning should occur only in the master or release branches because they go public.
  4. The development and nightly builds should be built from the development branches which can be versioned with build versions of any format, e.g. +201405231645, just to differentiate them from public releases and to specify the order in which they're built.

Hope this helps.

<!-- gh-comment-id:44011599 --> @zafarkhaja commented on GitHub (May 23, 2014): @mearns, I think your problem is not the problem SemVer is trying to solve. If you carefully read the introduction part of the specification you'll see that the main problem addressed by SemVer is the "dependency hell", and it's more about backward compatibility of APIs than anything else. What could help you, though, is a different approach to the development process and/or release management. Try a workflow similar to [A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/). A few points to note: 1. You have to bump a version only if it's a public release. You don't need to bump versions of development and nightly builds because they're not public and are subject to change. But, you can append a build version to the current normal version. 2. Using feature branches and a separate release branch will definitely let you know if the coming release breaks the backward compatibility of your API. 3. Versioning should occur only in the master or release branches because they go public. 4. The development and nightly builds should be built from the development branches which can be versioned with build versions of any format, e.g. `+201405231645`, just to differentiate them from public releases and to specify the order in which they're built. Hope this helps.
Author
Owner

@mearns commented on GitHub (May 23, 2014):

Dependency hell can only ever be addressed suitably if a sufficient number of people follow a standard which properly addresses it. Bottom line, it's no skin off my nose if semver doesn't work for me, I just won't use it. What I'm trying to point out is that I am not the only one who will run into these kinds of problems: there are lots of other individuals and teams who work in a similar way, or perhaps in a different manner which semver doesn't support because it is too restrictive. At the end of the day if the maintainer(s) of semver want it to address a problem, it needs to be widely adopted, and it will not be widely adopted if people cannot make it work for them.

Yes, I could try a particular work flow, but I'm not going to unless I have a compelling reason to, and compliance with semver is not compelling enough. And is this really what we want as a programming community? Everybody using the same workflow? We all benefit when people and teams work in the way that is most comfortable for them, and when people do things in different ways. Diversity pushes the field to new places.

To your point about development builds not being public releases: this is another assumption based on the way you may be used to developing. In many open projects (firefox, for instance), nightly builds are publicly available.

Even if it were the case that development builds are not public, bringing this up misses the broader picture. Logical, semantic version identifiers can be just as beneficial inside an organization as outside. As far as I as a developer am concerned, any time the code leaves my computer it's "released", even if it isn't to the general public. Why shouldn't my QA team get the same benefits from semantic versioning as the general public? Why shouldn't my entire organization be able to use a consistent versioning scheme throughout the entire lifecycle of the product?

The way we currently work (in my team, that is), we do this, and it's great. The QA team can automatically decide which tests to run based on the version because they can tell how it effected the API. They can unambiguously tell me what version a bug was discovered in, and I can always find the version in my revision control system. As goes for public releases, so goes for internal releases. The only issue (and it's not an issue for us) is that our versions aren't compliant with semver.

<!-- gh-comment-id:44044184 --> @mearns commented on GitHub (May 23, 2014): Dependency hell can only ever be addressed suitably if a sufficient number of people follow a standard which properly addresses it. Bottom line, it's no skin off my nose if semver doesn't work for me, I just won't use it. What I'm trying to point out is that I am not the only one who will run into these kinds of problems: there are lots of other individuals and teams who work in a similar way, or perhaps in a different manner which semver doesn't support because it is too restrictive. At the end of the day if the maintainer(s) of semver want it to address a problem, it needs to be widely adopted, and it will not be widely adopted if people cannot make it work for them. Yes, I could try a particular work flow, but I'm not going to unless I have a compelling reason to, and compliance with semver is not compelling enough. And is this really what we want as a programming community? Everybody using the same workflow? We all benefit when people and teams work in the way that is most comfortable for them, and when people do things in different ways. Diversity pushes the field to new places. To your point about development builds not being public releases: this is another assumption based on the way you may be used to developing. In many open projects (firefox, for instance), nightly builds are publicly available. Even if it were the case that development builds are not public, bringing this up misses the broader picture. Logical, semantic version identifiers can be just as beneficial inside an organization as outside. As far as I as a developer am concerned, any time the code leaves my computer it's "released", even if it isn't to the general public. Why shouldn't my QA team get the same benefits from semantic versioning as the general public? Why shouldn't my entire organization be able to use a consistent versioning scheme throughout the entire lifecycle of the product? The way we currently work (in my team, that is), we do this, and it's great. The QA team can automatically decide which tests to run based on the version because they can tell how it effected the API. They can unambiguously tell me what version a bug was discovered in, and I can always find the version in my revision control system. As goes for public releases, so goes for internal releases. The only issue (and it's not an issue for us) is that our versions aren't compliant with semver.
Author
Owner

@FichteFoll commented on GitHub (May 23, 2014):

@zafarkhaja, your 4. is actually what we are trying to solve here.

The problem with these "different" develop builds is that versions with only a different + build block have the same precedence.

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.

Thus, you may be able to create multiple builds whose string values but you wouldn't know which one is newer because they have the same precedence.

I already made two proposals above and I still think that these are the best options so far (slightly rephrased):

  1. Remove the clause from the spec that discourages using build metadata for precedence and instead limit it to only Dev (internal) releases, while applying the same rules as for pre-releases. Except that a version with build metadata is always higher than the one without.
  2. Just ignore the clause because it's only a "SHOULD".

I definitely favor the first one because it would be official and something you can rely on - assuming the corresponding version of the semver spec is supported.
(It would then use the same precedence rules as my pysemver implementation.)

<!-- gh-comment-id:44044442 --> @FichteFoll commented on GitHub (May 23, 2014): @zafarkhaja, your 4. is actually what we are trying to solve here. The problem with these "different" develop builds is that versions with only a different `+` build block have the same precedence. > 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. Thus, you may be able to create multiple builds whose string values but you wouldn't know which one is newer because they have _the same precedence_. I already made two proposals [above](https://github.com/mojombo/semver/issues/200#issuecomment-43722207) and I still think that these are the best options so far (slightly rephrased): > 1. Remove the clause from the spec that discourages using build metadata for precedence and instead limit it to only Dev (internal) releases, while applying the same rules as for pre-releases. Except that a version with build metadata is always higher than the one without. > 2. Just ignore the clause because it's only a "SHOULD". I definitely favor the first one because it would be official and something you can rely on - assuming the corresponding version of the semver spec is supported. (It would then use the same precedence rules as my [pysemver](https://github.com/FichteFoll/pysemver) implementation.)
Author
Owner

@mearns commented on GitHub (May 23, 2014):

@FichteFoll
I agree: your suggestion of how to use build-meta data for post-release identifier is pretty much exactly what I'm looking for. Making it part of the semver standard would likely solve all my concerns, though I'm not sure if it would require the major version on semver to bump.

Your suggestion also has a nice symmetry: the '-' ("minus") is used to indicate "pre-release" identifiers, and the '+' ("plus") is used for "post-release". It's like it was meant to be, except apparently it wasn't because it isn't how the standard is written.

<!-- gh-comment-id:44044929 --> @mearns commented on GitHub (May 23, 2014): @FichteFoll I agree: your suggestion of how to use build-meta data for post-release identifier is pretty much exactly what I'm looking for. Making it part of the semver standard would likely solve all my concerns, though I'm not sure if it would require the major version on semver to bump. Your suggestion also has a nice symmetry: the '-' ("minus") is used to indicate "pre-release" identifiers, and the '+' ("plus") is used for "post-release". It's like it was meant to be, except apparently it wasn't because it isn't how the standard is written.
Author
Owner

@FichteFoll commented on GitHub (May 23, 2014):

@mearns

In many open projects (firefox, for instance), nightly builds are publicly available.

You can not compare this to FireFox's release schema because they are using a fixed versioning system that is not really compatible with semver (increase major every 6 weeks). However, since they already know what version their next release is going to have they can freely declare their nightly releases as pre-releases and signal that with a semver-compliant pre-release specifier (e.g. 30.0.0-1.nightly.123 - I included the 1. because nightly comes after beta lexically).

<!-- gh-comment-id:44045314 --> @FichteFoll commented on GitHub (May 23, 2014): @mearns > In many open projects (firefox, for instance), nightly builds are publicly available. You can not compare this to FireFox's release schema because they are using a fixed versioning system that is not really compatible with semver (increase major every 6 weeks). However, since they already know what version their next release is going to have they can freely declare their nightly releases as pre-releases and signal that with a semver-compliant pre-release specifier (e.g. `30.0.0-1.nightly.123` - I included the `1.` because `nightly` comes after `beta` lexically).
Author
Owner

@mearns commented on GitHub (May 23, 2014):

@FichteFoll

You can not compare this to FireFox's release schema because they are using a fixed
versioning system that is not really compatible with semver

Ah, but isn't that my whole point? Semver is incompatible with the development process of a major open source project. They're using a different version system in part because semver is incompatible with the way they work.

When you say their version specifier is semver compliant, you're kind of blurring the concept of compliant. It will parse as a valid semver, but it is not semantically correct for a semver because it does not correlate with the public interface.

<!-- gh-comment-id:44071411 --> @mearns commented on GitHub (May 23, 2014): @FichteFoll > You can not compare this to FireFox's release schema because they are using a fixed > versioning system that is not really compatible with semver Ah, but isn't that my whole point? Semver is incompatible with the development process of a major open source project. They're using a different version system in part because semver is incompatible with the way they work. When you say their version specifier is semver compliant, you're kind of blurring the concept of compliant. It will parse as a valid semver, but it is not _semantically_ correct for a semver because it does not correlate with the public interface.
Author
Owner

@FichteFoll commented on GitHub (May 24, 2014):

Yes, you are right about that. I just wanted to point out that their release schema allowed them to use these many kinds of pre-release builds that semver would likely not.

<!-- gh-comment-id:44072900 --> @FichteFoll commented on GitHub (May 24, 2014): Yes, you are right about that. I just wanted to point out that their release schema allowed them to use these many kinds of pre-release builds that semver would likely not.
Author
Owner

@crazedsanity commented on GitHub (May 26, 2014):

Does the public API for Firefox introduce backwards-incompatible changes every six weeks, or are they simply using the major version number as a way of bringing more focus to the fact that there's been an update? I would imagine it is the latter, not the former, therefore making Firefox a poor example (or a good example of poor versioning), though I'll admit I haven't looked at the actual change logs to verify this assumption.

<!-- gh-comment-id:44158278 --> @crazedsanity commented on GitHub (May 26, 2014): Does the public API for Firefox introduce backwards-incompatible changes every six weeks, or are they simply using the major version number as a way of bringing more focus to the fact that there's been an update? I would imagine it is the latter, not the former, therefore making Firefox a poor example (or a good example of poor versioning), though I'll admit I haven't looked at the actual change logs to verify this assumption.
Author
Owner

@mearns commented on GitHub (May 27, 2014):

I've never reviewed firefox releases in enough detail to know whether or not their public API changes with every release. As far as I know, the only semantics behind their version number is "this is our new major release".

My point was not that firefox is using version numbers in a better way, or even in a good way. My point was simply that this is a very popular and very large open source project whose development and release process is incompatible with semver due to the publicly released nightly builds. So if they ever decided that they wanted to use semver, they would not be able to (at least not without drastically changing the way they work, which in my opinion is not the point of a standard like semver).

<!-- gh-comment-id:44268164 --> @mearns commented on GitHub (May 27, 2014): I've never reviewed firefox releases in enough detail to know whether or not their public API changes with every release. As far as I know, the only semantics behind their version number is "this is our new major release". My point was not that firefox is using version numbers in a better way, or even in a good way. My point was simply that this is a very popular and very large open source project whose development and release process is _incompatible_ with semver due to the publicly released nightly builds. So if they ever decided that they _wanted_ to use semver, they would not be able to (at least not without drastically changing the way they work, which in my opinion is not the point of a standard like semver).
Author
Owner

@crazedsanity commented on GitHub (May 27, 2014):

In the case of a large open source project, or most large projects, there are planned changes. Those changes are known ahead of time, and the general impact to the product's API are fairly well known, so the nightly builds can quite easily be geared toward that.

We've been going round and round on it, but it seems like the major misunderstanding is in the document around the word "SHOULD," which is just a recommendation. Allowing build meta data to establish precedence on an otherwise identical version string seems perfectly acceptable to me.

I would suggest that we basically go with the change suggested by @FichteFoll. Basically just clarify the statement in item 11 of the spec, indicating that build meta data MAY be used for precedence in a development environment or in the case of nightly builds.

Does this solve the problem?

<!-- gh-comment-id:44270443 --> @crazedsanity commented on GitHub (May 27, 2014): In the case of a large open source project, or most large projects, there are planned changes. Those changes are known ahead of time, and the general impact to the product's API are fairly well known, so the nightly builds can quite easily be geared toward that. We've been going round and round on it, but it seems like the major misunderstanding is in the document around the word "SHOULD," which is just a recommendation. Allowing build meta data to establish precedence on an otherwise identical version string seems perfectly acceptable to me. I would suggest that we basically go with the change suggested by @FichteFoll. Basically just clarify the statement in item 11 of the spec, indicating that build meta data MAY be used for precedence in a development environment or in the case of nightly builds. Does this solve the problem?
Author
Owner

@zafarkhaja commented on GitHub (May 27, 2014):

It was discussed on several occasions whether SemVer should be compatible with the versioning schemes of large open source projects or not (e.g. #145). And the thing is SemVer can't please everyone. I think it should evolve independently picking up only the best practices from those projects.

@FichteFoll it's not SHOULD anymore, see #151. By the way, I, too, have a separate Comparator in my implementation which allows for sorting of the build metadata.

<!-- gh-comment-id:44277529 --> @zafarkhaja commented on GitHub (May 27, 2014): It was discussed on several occasions whether SemVer should be compatible with the versioning schemes of large open source projects or not (e.g. #145). And the thing is SemVer can't please everyone. I think it should evolve independently picking up only the best practices from those projects. @FichteFoll it's not `SHOULD` anymore, see #151. By the way, I, too, have a separate `Comparator` in my implementation which allows for sorting of the build metadata.
Author
Owner

@crazedsanity commented on GitHub (May 27, 2014):

I suppose the discussion would be better served if everyone were referring to the master copy of the spec.

That said, I think it would be detrimental to ignore the case of nightly builds. While I agree that it is unwise to attempt to please every case, I think this one is deserving of at least some attention.

<!-- gh-comment-id:44278678 --> @crazedsanity commented on GitHub (May 27, 2014): I suppose the discussion would be better served if everyone were referring to the [master copy of the spec](https://github.com/mojombo/semver/blob/master/semver.md). That said, I think it would be detrimental to ignore the case of nightly builds. While I agree that it is unwise to attempt to please every case, I think this one is deserving of at least some attention.
Author
Owner

@mearns commented on GitHub (May 27, 2014):

I agree with the recommendation that the spec remove the (current) explicit prohibition against using metadata to determine precedence, and additionally to at least encourage (if not mandate) that it in fact is considered for precedence.

As far as pleasing everyone, I will simply reiterate what I previously said: if semver is going to make a difference in the world of software development, it needs to be widely adopted. I agree that you simply cannot make everyone happy, but the standard should be as widely applicable as possible. The current document seems unnecessarily restrictive as I have described, which will hinder adoption. I've heard many suggestions of how to work around my issue, or change my development style, or reinterpret the standard, but I haven't heard any reasons why the current restriction is in any way helpful, let alone why it is important enough to justify a less inclusive spec.

<!-- gh-comment-id:44280968 --> @mearns commented on GitHub (May 27, 2014): I agree with the recommendation that the spec remove the (current) explicit prohibition against using metadata to determine precedence, and additionally to at least encourage (if not mandate) that it in fact _is_ considered for precedence. As far as pleasing everyone, I will simply reiterate what I previously said: if semver is going to make a difference in the world of software development, it needs to be widely adopted. I agree that you simply cannot make everyone happy, but the standard should be as widely applicable as possible. The current document seems unnecessarily restrictive as I have described, which will hinder adoption. I've heard many suggestions of how to work around my issue, or change my development style, or reinterpret the standard, but I haven't heard any reasons why the current restriction is in any way helpful, let alone why it is important enough to justify a less inclusive spec.
Author
Owner

@FichteFoll commented on GitHub (May 27, 2014):

The current restriction is probably only targeted at preventing people from releasing two different versions with the same major, minor and patch component, which I agree is very rightful to do. But for internal development releases they still serve a nice and clean workflow which certainly should not be ignored by the spec.

So, does any of the collaborators have an opinion on this? Should someone propose a pull request? (I can only do it next week.)

<!-- gh-comment-id:44310475 --> @FichteFoll commented on GitHub (May 27, 2014): The current restriction is probably only targeted at preventing people from releasing two different versions with the same major, minor and patch component, which I agree is very rightful to do. But for internal development releases they still serve a nice and clean workflow which certainly should not be ignored by the spec. So, does any of the collaborators have an opinion on this? Should someone propose a pull request? (I can only do it next week.)
Author
Owner

@mearns commented on GitHub (May 28, 2014):

I'll propose a pull-request shortly.

<!-- gh-comment-id:44399303 --> @mearns commented on GitHub (May 28, 2014): I'll propose a pull-request shortly.
Author
Owner

@crazedsanity commented on GitHub (May 28, 2014):

This proposal seems good to me. +1

<!-- gh-comment-id:44424542 --> @crazedsanity commented on GitHub (May 28, 2014): This proposal seems good to me. +1
Author
Owner

@mar10 commented on GitHub (Jun 11, 2014):

A bit late to the party, but I came accross this disucussion when trying to figure out "which version should I set after I released v1.2.3 and now start a new development cycle"?

I guess this is comparable to 'nightly builds'.

§3 from the spec says

Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications MUST be released as a new version.

I use a public GitHub repository, so pushing intermediate work is a bit like releasing.
I also want to push a new version to GitHub to make clear that

  • this is no longer the released, tagged version anymore
  • this code is not guaranteed to be stable
  • no dependency resolver should consider this code (except when development code is explicitly accepted)

§10 says

Build metadata MAY be denoted by appending a plus sign [...].
Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence.

Even when this is changed to 'SHOULD be considered', it is not guaranteed that bower will deliver my unstable 1.2.3+dev version(?)

§9 says

A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch 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. [...]

So currently I have to increment and mark as pre-release.

Since I don't know if the next release will be major, minor or patch it could be 2.0.0-dev, 1.3.0-dev, or 1.2.4-dev.
I choose patch, even if the nightly code contains API changes. Reason: I might change my mind before the next release, but 2.0.0-dev is still greater than 1.2.4, so decrementing later is impossible.

So my conclusion is: bump to 1.2.4-dev, or maybe 1.2.4-dev.20140611 for nightly builds after 1.2.3.

If we want to allow '1.2.3+dev' for nightly builds with SEMVER, I think we should modify §10 to state that 'releases with build metadata MUST be considered unstable' and maybe 'precedence MUST be considered'. (Which is a major change and bumps semver to 3.0.0 ;-)

Makes sense? I'd be interested in your thoughts.

<!-- gh-comment-id:45793417 --> @mar10 commented on GitHub (Jun 11, 2014): A bit late to the party, but I came accross this disucussion when trying to figure out "which version should I set after I released v1.2.3 and now start a new development cycle"? I guess this is comparable to 'nightly builds'. §3 from the spec says > Once a versioned package has been released, the contents of that version MUST NOT be modified. Any modifications MUST be released as a new version. I use a public GitHub repository, so pushing intermediate work is a bit like releasing. I also want to push a new version to GitHub to make clear that - this is no longer the released, tagged version anymore - this code is not guaranteed to be stable - no dependency resolver should consider this code (except when development code is explicitly accepted) §10 says > Build metadata MAY be denoted by appending a plus sign [...]. > Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Even when this is changed to 'SHOULD be considered', it is not guaranteed that bower will deliver my unstable 1.2.3+dev version(?) §9 says > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch 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. [...] So currently I have to increment and mark as pre-release. Since I don't know if the next release will be major, minor or patch it could be 2.0.0-dev, 1.3.0-dev, or 1.2.4-dev. I choose patch, even if the nightly code contains API changes. Reason: I might change my mind before the next release, but 2.0.0-dev is still greater than 1.2.4, so decrementing later is impossible. So my conclusion is: bump to 1.2.4-dev, or maybe 1.2.4-dev.20140611 for nightly builds after 1.2.3. If we want to allow '1.2.3+dev' for nightly builds with SEMVER, I think we should modify §10 to state that 'releases with build metadata MUST be considered unstable' and maybe 'precedence MUST be considered'. (Which is a major change and bumps semver to 3.0.0 ;-) Makes sense? I'd be interested in your thoughts.
Author
Owner

@mearns commented on GitHub (Jun 16, 2014):

I like your proposal, but it's a harder sell because it breaks compatibility with the current standard. I'm mostly just glad to see additional voices wanting this feature to be supported so that the authors can see how important it is to support this type of development.

<!-- gh-comment-id:46211314 --> @mearns commented on GitHub (Jun 16, 2014): I like your proposal, but it's a harder sell because it breaks compatibility with the current standard. I'm mostly just glad to see additional voices wanting this feature to be supported so that the authors can see how important it is to support this type of development.
Author
Owner

@dwijnand commented on GitHub (Jun 24, 2014):

Note, this was somewhat discussed in #124, particularly https://github.com/mojombo/semver/issues/124#issuecomment-20484470

<!-- gh-comment-id:46944113 --> @dwijnand commented on GitHub (Jun 24, 2014): Note, this was somewhat discussed in #124, particularly https://github.com/mojombo/semver/issues/124#issuecomment-20484470
Author
Owner

@zafarkhaja commented on GitHub (Jun 27, 2014):

After reading the arguments in this thread and giving some thought to the matter, it's now starting to make some sense to me. And although I've never used such a workflow and never had to, I admit that life is complicated and that sometimes there may be different situations and different requirements.

So, having said that, I'd like to make a proposition, a backward incompatible one though.

The build metadata prefix (the + sign currently) should be changed to ~ (or any other character, it's just that tilde feels more natural to me) and + should be released in favor of "post-release" changes because + goes well with - (pre-release) and is a direct contrast, hence it's more natural and intuitive.

A small example by tradition:

  1. You start off with version 0.1.0
  2. You approach the first stable release, so you dump the version to 1.0.0-pre
  3. You ship the stable release of 1.0.0 when it's ready
  4. You are not sure what the next version will be, so you make it 1.0.0+post

Meanwhile, different builds can have their build versions:
1.0.0-pre20140212
1.0.0
201406271340
1.0.0+post~b186e61

The build versions SHOULD be ignored when determining the precedence as before and the post-release versions, on the other hand, MUST be taken into account.

<!-- gh-comment-id:47330860 --> @zafarkhaja commented on GitHub (Jun 27, 2014): After reading the arguments in this thread and giving some thought to the matter, it's now starting to make some sense to me. And although I've never used such a workflow and never had to, I admit that life is complicated and that sometimes there may be different situations and different requirements. So, having said that, I'd like to make a proposition, a backward incompatible one though. The build metadata prefix (the `+` sign currently) should be changed to `~` (or any other character, it's just that tilde feels more natural to me) and `+` should be released in favor of "post-release" changes because `+` goes well with `-` (pre-release) and is a direct contrast, hence it's more natural and intuitive. A small example by tradition: 1. You start off with version 0.1.0 2. You approach the first stable release, so you dump the version to 1.0.0-pre 3. You ship the stable release of 1.0.0 when it's ready 4. You are not sure what the next version will be, so you make it 1.0.0+post Meanwhile, different builds can have their build versions: 1.0.0-pre~20140212 1.0.0~201406271340 1.0.0+post~b186e61 The build versions SHOULD be ignored when determining the precedence as before and the post-release versions, on the other hand, MUST be taken into account.
Author
Owner

@FichteFoll commented on GitHub (Jun 27, 2014):

I'm fine with that, even though this would bump semver to 3.0.0.

The only other valuable option I see is to combine the post-release field into metadata, but that's not what metadata is supposed to be and makes it overloaded. So I think introducing a new field would be the best option. I also like your symbol choices, notably ~ for metadata.

Should semver also restrict the use of only one of the pre- or post-release specifier? Like, is 1.0.0-beta.1+test14 a valid build ot would it have to be 1.0.0-beta.1.test14? (I prefer it being possible.)

<!-- gh-comment-id:47332482 --> @FichteFoll commented on GitHub (Jun 27, 2014): I'm fine with that, even though this would bump semver to 3.0.0. The only other valuable option I see is to combine the post-release field into metadata, but that's not what metadata is supposed to be and makes it overloaded. So I think introducing a new field would be the best option. I also like your symbol choices, notably `~` for metadata. Should semver also restrict the use of only one of the pre- or post-release specifier? Like, is `1.0.0-beta.1+test14` a valid build ot would it have to be `1.0.0-beta.1.test14`? (I prefer it being possible.)
Author
Owner

@zafarkhaja commented on GitHub (Jun 27, 2014):

@FichteFoll that's right, the post-release version should be a separate identifier on its own just like the pre-release version, and, indeed, metadata is different and as its name implies it's OK to ignore it, which can't be said about the post-release version.
Consider bumping the major version here as a necessary evil, if evil at all.
Regarding combining the pre- and post-release versions, I personally don't see any downsides to this, so I guess it should be fine. An example of it could be as follows:
Suppose you release 1.0.0-alpha.1. And then you are not sure if the next version will be 1.0.0-alpha.2 or 1.0.0-beta.1 or even 1.0.0-rc.1 if it turns out to be stable enough. So you can ship some of the changes following the previous release under 1.0.0-alpha+sth until you're sure what the next version will be.
The example might be unrealistic, but i think it conveys the idea.

<!-- gh-comment-id:47333436 --> @zafarkhaja commented on GitHub (Jun 27, 2014): @FichteFoll that's right, the post-release version should be a separate identifier on its own just like the pre-release version, and, indeed, metadata is different and as its name implies it's OK to ignore it, which can't be said about the post-release version. Consider bumping the major version here as a necessary evil, if evil at all. Regarding combining the pre- and post-release versions, I personally don't see any downsides to this, so I guess it should be fine. An example of it could be as follows: Suppose you release `1.0.0-alpha.1`. And then you are not sure if the next version will be `1.0.0-alpha.2` or `1.0.0-beta.1` or even `1.0.0-rc.1` if it turns out to be stable enough. So you can ship some of the changes following the previous release under `1.0.0-alpha+sth` until you're sure what the next version will be. The example might be unrealistic, but i think it conveys the idea.
Author
Owner

@EddieGarmon commented on GitHub (Jun 27, 2014):

Apparently the value of SemVer is being missed in this thread.

The notion of a 'post' release release that does not tell you about the changes goes completely against what SemVer is trying to accomplish.

And yes, if this were introduced where '+' was repurposed, then the spec would have to be bumped to 3.0.0 as that is a breaking change, no matter how you feel about it.

<!-- gh-comment-id:47334183 --> @EddieGarmon commented on GitHub (Jun 27, 2014): Apparently the value of SemVer is being missed in this thread. The notion of a 'post' release release that does not tell you about the changes goes completely against what SemVer is trying to accomplish. And yes, if this were introduced where '+' was repurposed, then the spec would have to be bumped to 3.0.0 as that is a breaking change, no matter how you **feel** about it.
Author
Owner

@zafarkhaja commented on GitHub (Jun 27, 2014):

@EddieGarmon if you read my first comment in this thread (link), my first reaction was similar to yours. So, basically I agree with you. But on the other hand, nightly builds are widely adopted, so why not make SemVer more flexible to support different workflows.
To be honest, I'm pretty much happy with how things are now, but should we ever want to introduce something like this to the spec, that is how I see it.

<!-- gh-comment-id:47336107 --> @zafarkhaja commented on GitHub (Jun 27, 2014): @EddieGarmon if you read my first comment in this thread ([link](https://github.com/mojombo/semver/issues/200#issuecomment-44011599)), my first reaction was similar to yours. So, basically I agree with you. But on the other hand, nightly builds are widely adopted, so why not make SemVer more flexible to support different workflows. To be honest, I'm pretty much happy with how things are now, but should we ever want to introduce something like this to the spec, that is how I see it.
Author
Owner

@EddieGarmon commented on GitHub (Jun 27, 2014):

I also agree that nightly builds are useful, and are becoming more adopted, which is a good thing.

SemVer is flexible, but at the same time, its is very strict about telling you the level of API change, so that your consumers know the level of pain they could feel when deciding to take an upgraded version. SemVer is all about communication of the level of the API.

If you are not releasing nightlies for external consumption, the simplest thing you could do is just bump the patch and add a prerelease tag with an incrementing build counter. If you are releasing nightlies, I would highly recommend updating your tool chain, as I personally would stop using a component that fibbed about using SemVer.

Consumers time is valuable, let them know the level of investment they will need to make to look at the new hotness...

<!-- gh-comment-id:47337877 --> @EddieGarmon commented on GitHub (Jun 27, 2014): I also agree that nightly builds are useful, and are becoming more adopted, which is a good thing. SemVer is flexible, but at the same time, its is very strict about telling you the level of API change, so that your consumers know the level of pain they could feel when deciding to take an upgraded version. SemVer is **all about communication** of the level of the API. If you are not releasing nightlies for external consumption, the simplest thing you could do is just bump the patch and add a prerelease tag with an incrementing build counter. If you are releasing nightlies, I would highly recommend updating your tool chain, as I personally would stop using a component that fibbed about using SemVer. Consumers time is valuable, let them know the level of investment they will need to make to look at the new hotness...
Author
Owner

@FichteFoll commented on GitHub (Jun 27, 2014):

The idea behind post-releases is that these are development versions and not intended for the (wide) public at all, because that's what the other part of semver is for: major to patch (& pre-release).
If you, as a consumer, use a post-release (alas developer) version you should know very well that you're on the bleeding edge and can't consider the version stable.

the simplest thing you could do is just bump the patch and add a prerelease tag with an incrementing build counter.

This is the closest currently available workaround, yes, but do you really think it is better? We're here to improve semver and this proposal is a good improvement imo, if only for the long-term.

Compare the following versions for example:
currently: 1.0.0+2014.6.26 -> 1.0.1-aaa.dev.1+2014.6.27
(aaa is to make sure that we can release a higher alpha pre-release version later since a is the lowest in precedence)
with the change: 1.0.0~2014.6.26 -> 1.0.0+dev.1~2014.6.27

<!-- gh-comment-id:47341267 --> @FichteFoll commented on GitHub (Jun 27, 2014): The idea behind post-releases is that these are _development versions_ and not intended for the (wide) public _at all_, because that's what the other part of semver is for: major to patch (& pre-release). If you, as a consumer, use a post-release (alas developer) version you should know very well that you're on the bleeding edge and can't consider the version stable. > the simplest thing you could do is just bump the patch and add a prerelease tag with an incrementing build counter. This is the closest currently available workaround, yes, but do you really think it is better? We're here to improve semver and this proposal is a good improvement imo, if only for the long-term. Compare the following versions for example: currently: `1.0.0+2014.6.26` -> `1.0.1-aaa.dev.1+2014.6.27` (`aaa` is to make sure that we can release a higher `alpha` pre-release version later since `a` is the lowest in precedence) with the change: `1.0.0~2014.6.26` -> `1.0.0+dev.1~2014.6.27`
Author
Owner

@EddieGarmon commented on GitHub (Jun 27, 2014):

Even as a developer on the bleeding edge, I still want to have communicated to me what the level of changes are.

<!-- gh-comment-id:47343265 --> @EddieGarmon commented on GitHub (Jun 27, 2014): Even as a developer on the bleeding edge, I still want to have communicated to me what the level of changes are.
Author
Owner

@mearns commented on GitHub (Jun 28, 2014):

@EddieGarmon

If you are not releasing nightlies for external consumption, the simplest thing you could do is just bump the patch and add a prerelease tag with an incrementing build counter.

First, that violates semver, because bumping the patch may not be the appropriate rev for the changes in the nightly. So if your version already doesn't accurately tell you about the API changes, how is this different from the post-build identifiers we've been outlining? That's your major concern, right, that a post-build version string doesn't give you sufficient information? Your solution doesn't either.

Second, differentiating between internal and external releases is short sighted and introduces a false dichotomy. It also misses the potential usefulness of semver for internal teams.

As I've pointed out many times, post build identifiers are a requirement for many teams. If semver doesn't support them, then semver just won't be used. My team is already using a variation on semver that uses a post build identifier much as has been described here. It's a super set of semver that's more widely applicable. If this issue isn't resolved in semver, then we're just going to release ours as a competing and more useful standard. It makes no difference to us, we're just trying to make things a little easier by integrating into an existing standard.

<!-- gh-comment-id:47424472 --> @mearns commented on GitHub (Jun 28, 2014): @EddieGarmon > If you are not releasing nightlies for external consumption, the simplest thing you could do is just bump the patch and add a prerelease tag with an incrementing build counter. First, that violates semver, because bumping the patch may not be the appropriate rev for the changes in the nightly. So if your version already doesn't accurately tell you about the API changes, how is this different from the post-build identifiers we've been outlining? That's your major concern, right, that a post-build version string doesn't give you sufficient information? Your solution doesn't either. Second, differentiating between internal and external releases is short sighted and introduces a false dichotomy. It also misses the potential usefulness of semver for internal teams. As I've pointed out many times, post build identifiers are a requirement for many teams. If semver doesn't support them, then semver just won't be used. My team is already using a variation on semver that uses a post build identifier much as has been described here. It's a super set of semver that's more widely applicable. If this issue isn't resolved in semver, then we're just going to release ours as a competing and more useful standard. It makes no difference to us, we're just trying to make things a little easier by integrating into an existing standard.
Author
Owner

@haacked commented on GitHub (Jul 1, 2014):

Continuing with your scenario, lets your change was to add a function to the public interface, you did created version 1.3.0-dev.1. What do you do when management decides they don't want this feature after all. You remove it, and what do you set the version to? To adhere to semver, you need to mark the version number as 2.0.0 (or 2.0.0-dev.1, for instance)

Wait, if you add a feature to 1.3.0-dev.1 and then remove the feature, why would you need to change the major version?

In section 9 it states:

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

That seems to directly address the situation you described. If you remove the feature and it was never released as a stable release, then you're fine keeping it on the 1.3.0-dev.* line.

My point is that the semantics encapsulated in semver are too limited to support a very common development style,

That's by design. SemVer is focused on public versions.

Even if it were the case that development builds are not public, bringing this up misses the broader picture. Logical, semantic version identifiers can be just as beneficial inside an organization as outside.

Indeed. This is why we intentionally did not give build metadata precedence. In the original discussion, various teams had specific development workflows in regards to nightly builds. Some directly contradict your proposal.

We realize that semantic identifiers can be beneficial within an organization. And organizations are free to layer semantics on build metadata. Just as long as the public releases comply.

My recommendation would be for such package managers to have a mode for internal usage.

For example, I would expect Ruby Gems to continue to support the current rules about build metadata. But you could imagine a private install of ruby gems within an organization might support different semantics of build metadata.

<!-- gh-comment-id:47609705 --> @haacked commented on GitHub (Jul 1, 2014): > Continuing with your scenario, lets your change was to add a function to the public interface, you did created version 1.3.0-dev.1. What do you do when management decides they don't want this feature after all. You remove it, and what do you set the version to? To adhere to semver, you need to mark the version number as 2.0.0 (or 2.0.0-dev.1, for instance) Wait, if you add a feature to `1.3.0-dev.1` and then remove the feature, why would you need to change the major version? In section 9 it states: > 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 That seems to directly address the situation you described. If you remove the feature and it was never released as a stable release, then you're fine keeping it on the `1.3.0-dev.*` line. > My point is that the semantics encapsulated in semver are too limited to support a very common development style, That's by design. SemVer is focused on public versions. > Even if it were the case that development builds are not public, bringing this up misses the broader picture. Logical, semantic version identifiers can be just as beneficial inside an organization as outside. Indeed. This is why we intentionally did _not_ give build metadata precedence. In the original discussion, various teams had specific development workflows in regards to nightly builds. Some directly contradict your proposal. We realize that semantic identifiers can be beneficial within an organization. And organizations are free to layer semantics on build metadata. Just as long as the public releases comply. My recommendation would be for such package managers to have a mode for internal usage. For example, I would expect Ruby Gems to continue to support the current rules about build metadata. But you could imagine a private install of ruby gems within an organization might support different semantics of build metadata.
Author
Owner

@haacked commented on GitHub (Jul 1, 2014):

I seem to recall @serialseb having strong feelings about this.

<!-- gh-comment-id:47609863 --> @haacked commented on GitHub (Jul 1, 2014): I seem to recall @serialseb having strong feelings about this.
Author
Owner

@jeffhandley commented on GitHub (Jul 1, 2014):

Why we need metadata without precedence

Multiple build configurations

One of the scenarios we're expecting for NuGet was relying on the build metadata not implying precedence. Consider these semver versions:

  • 1.0.0-alpha.1+debug-x86
  • 1.0.0-alpha.1+debug-x64
  • 1.0.0-alpha.1+release-x86
  • 1.0.0-alpha.1+release-x64

Each of those builds (of the same version, from the same commit) would contain metadata inside the package (nuspec) that provides the information for their configuration (debug vs. release) and their architecture (x86 vs. x64). When NuGet is reasoning over the versions of the package available, it would see all 4 builds of version 1.0.0-alpha.1 and need to make a decision about which build to select. The consumer's project information would provide the context--we'd know if the project is being built in debug mode (justifying the debug build of the package) and we'd know which architecture is being targeted too.

In that scenario, it's important that the build metadata doesn't denote precedence--merely metadata that distinguishes builds from one another (providing uniqueness). And of course, there'd be no parsing of the metadata to extract meaning--the important data would come from inside the package.

Parallel build servers

Another scenario that was referenced when deciding that build metadata SHOULD not imply precedence was when you have multiple build servers. If you have 2 build servers churning on the same project (happens in large organizations), you could have the following situation:

  1. Commit FFFFF1 occurs, Build server A starts a build
  2. Commit EEEEE2 occurs, Build server B starts a build
  3. Build server B finishes first and produces build 1.0.0-dev.1+EEEEE2.B
  4. Build server A finishes second and produces build 1.0.0-dev.1+FFFFF1.A

How can you determine precedence between the two builds? We know that commit FFFFF1 happened first, but its commit hash and build completion time are "greater than" the build of EEEEE2.

Development builds

With that said, I think we definitely need to pick a way to address the development cycles where things are happening before you choose a new version. It is awkward to pick a new version when you don't know what that version is going to be.

Internal references

Consider the scenario where your project produces:

  • Acme.Ammunition.Core
  • Acme.Ammunition.Bombs
  • Acme.Ammunition.Bullets

If you're working on the next release of the Acme.Ammunition packages, you're very likely to be changing Core, Bombs, and Bullets together. You add some new API into Core and need to immediately consume it from Bombs and Bullets, before publishing a new package anywhere. What should the dependency version from Bombs/Bullets to Core be?

Referring to versions

In order to answer the above question, we should recognize that the SemVer spec doesn't cover Version Ranges/Specs at all. Nowhere in the SemVer spec does it mention how dependencies on versions are declared. SemVer presently only defines how to assign version numbers; it doesn't define how to refer to them. Perhaps this is the root cause of this issue.

Microsoft's ASP.NET vNext is facing this problem. Their project.json file supports an * character in version references, allowing for the package manager to find the latest dev build matching the version number to the left of the *--it's basically a wildcard but there are more detailed semantics. This is alluded to but not clearly defined in their Sandbox Samples documentation.

Wrong question?

Maybe before we can resolve this issue of how to format version numbers representing development builds, we should talk about how we refer to version numbers, define some semantics over that, and then see what we need to add to the version numbers themselves to accomodate it?

<!-- gh-comment-id:47613610 --> @jeffhandley commented on GitHub (Jul 1, 2014): ## Why we need metadata without precedence ### Multiple build configurations One of the scenarios we're expecting for NuGet was relying on the build metadata not implying precedence. Consider these semver versions: - 1.0.0-alpha.1+debug-x86 - 1.0.0-alpha.1+debug-x64 - 1.0.0-alpha.1+release-x86 - 1.0.0-alpha.1+release-x64 Each of those builds (of the same version, from the same commit) would contain metadata inside the package (nuspec) that provides the information for their configuration (debug vs. release) and their architecture (x86 vs. x64). When NuGet is reasoning over the versions of the package available, it would see all 4 builds of version 1.0.0-alpha.1 and need to make a decision about which build to select. The consumer's project information would provide the context--we'd know if the project is being built in debug mode (justifying the debug build of the package) and we'd know which architecture is being targeted too. In that scenario, it's important that the build metadata doesn't denote precedence--merely metadata that distinguishes builds from one another (providing uniqueness). And of course, there'd be no parsing of the metadata to extract meaning--the important data would come from inside the package. ### Parallel build servers Another scenario that was referenced when deciding that build metadata SHOULD not imply precedence was when you have multiple build servers. If you have 2 build servers churning on the same project (happens in large organizations), you could have the following situation: 1. Commit FFFFF1 occurs, Build server A starts a build 2. Commit EEEEE2 occurs, Build server B starts a build 3. Build server B finishes first and produces build `1.0.0-dev.1+EEEEE2.B` 4. Build server A finishes second and produces build `1.0.0-dev.1+FFFFF1.A` How can you determine precedence between the two builds? We know that commit FFFFF1 happened first, but its commit hash and build completion time are "greater than" the build of EEEEE2. ## Development builds With that said, I think we definitely need to pick a way to address the development cycles where things are happening before you choose a new version. It is awkward to pick a new version when you don't know what that version is going to be. ### Internal references Consider the scenario where your project produces: - Acme.Ammunition.Core - Acme.Ammunition.Bombs - Acme.Ammunition.Bullets If you're working on the next release of the Acme.Ammunition packages, you're very likely to be changing Core, Bombs, and Bullets together. You add some new API into Core and need to immediately consume it from Bombs and Bullets, before publishing a new package anywhere. What should the dependency version from Bombs/Bullets to Core be? ### Referring to versions In order to answer the above question, we should recognize that the SemVer spec doesn't cover Version Ranges/Specs at all. Nowhere in the SemVer spec does it mention how dependencies on versions are declared. SemVer presently only defines how to assign version numbers; it doesn't define how to refer to them. Perhaps this is the root cause of this issue. Microsoft's ASP.NET vNext is facing this problem. Their project.json file supports an `*` character in version references, allowing for the package manager to find the latest dev build matching the version number to the left of the `*`--it's basically a wildcard but there are more detailed semantics. This is alluded to but not clearly defined in their [Sandbox Samples documentation](https://github.com/aspnet/home#sandbox-samples). ## Wrong question? Maybe before we can resolve this issue of how to format version numbers representing development builds, we should talk about how we refer to version numbers, define some semantics over that, and then see what we need to add to the version numbers themselves to accomodate it?
Author
Owner

@FichteFoll commented on GitHub (Jul 1, 2014):

I think instead of "referring to versions" you mean "selecting versions"? This should be a separate issue though.

FWIW here is what my implementation is capable of, inspired by node's semver: 6efb9253dd/semver.py (L597-L617)
I plan to make 1 equivalent to ~1 and add wildcard compatability to only match version that also match the metadata specified, so you could get the highest available version using max(SemSel(" *+release-x64").matches([SemVer(...), ...])).

<!-- gh-comment-id:47635262 --> @FichteFoll commented on GitHub (Jul 1, 2014): I think instead of "referring to versions" you mean "selecting versions"? This should be a separate issue though. FWIW here is what my implementation is capable of, inspired by node's semver: https://github.com/FichteFoll/pysemver/blob/6efb9253dd44521823a25d5c26d9fbc01958fbaa/semver.py#L597-L617 I plan to make `1` equivalent to `~1` and add wildcard compatability to only match version that also match the metadata specified, so you could get the highest available version using `max(SemSel(" *+release-x64").matches([SemVer(...), ...]))`.
Author
Owner

@jeffhandley commented on GitHub (Jul 1, 2014):

Referring to versions, selecting versions, yeah-sounds like the same idea.

Essentially, how does the consumer of a package specify the version ranges to select the appropriate version of a package?

Take NuGet's documentation for specifying version ranges for example. It has syntax for min, max, min+max, inclusive/exclusive, exact, and latest version.

I think that as part of defining how package versions communicate that they are dev/daily builds or whatnot, we need to look at how those versions will be consumed. In order to know how they're consumed, we should look at defining a new part of the spec that explains how to write version range specs.

I'll file a new issue to propose that semver gets augmented to include a new section for version range spec syntaxes and meanings.

<!-- gh-comment-id:47689880 --> @jeffhandley commented on GitHub (Jul 1, 2014): Referring to versions, selecting versions, yeah-sounds like the same idea. Essentially, how does the consumer of a package specify the version ranges to select the appropriate version of a package? Take [NuGet's documentation for specifying version ranges](http://docs.nuget.org/docs/reference/versioning#Specifying_Version_Ranges_in_.nuspec_Files) for example. It has syntax for min, max, min+max, inclusive/exclusive, exact, and latest version. I think that as part of defining how package versions communicate that they are dev/daily builds or whatnot, we need to look at how those versions will be consumed. In order to know how they're consumed, we should look at defining a new part of the spec that explains how to write version range specs. I'll file a new issue to propose that semver gets augmented to include a new section for version range spec syntaxes and meanings.
Author
Owner

@JamesMGreene commented on GitHub (Jun 9, 2015):

By the way, please take a look at this semi-related issue that I opened, discussed, and ended up closing: #242

The discussion may be more specific to my particular use case (wrapping an external dependency) but there's definitely a substantial amount of merit/insight to be gained within, IMHO. You can ignore the opening discussion and skip ahead to where we discuss build metadata (in the fashion akin to @jeffhandley's notes here for NuGet).

Additionally, I would strongly agree that we really still need post-release versioning added to SemVer while also maintaining the build metadata concept (but ideally with an indicator other than the misappropriated + 😉).

<!-- gh-comment-id:110441881 --> @JamesMGreene commented on GitHub (Jun 9, 2015): By the way, please take a look at this semi-related issue that I opened, discussed, and ended up closing: #242 The discussion may be more specific to my particular use case (wrapping an external dependency) but there's definitely a substantial amount of merit/insight to be gained within, IMHO. You can ignore the opening discussion and skip ahead to where we discuss build metadata (in the fashion akin to @jeffhandley's notes here for NuGet). Additionally, I would strongly agree that we really still need post-release versioning added to SemVer while _also_ maintaining the build metadata concept (but ideally with an indicator other than the misappropriated `+` :wink:).
Author
Owner

@Abdillah commented on GitHub (Jul 28, 2015):

I have some view on this (nightly build).

When RAD or Nightly Build is applied, I assume that pre-release is vacum; means the development do not need to use alpha, beta, etc. Is it right @mearns?

Then, why don't we propose SemVer to give more freedom on this pre-release "tuple"? I mean instead of specify after a dash is pre-release, SemVer can generalize that it is a tuple representing development stage. It can either pre-release or post-release. But, a project MUST consistent on using it and MUST included explanation on documentation. Moreover, whether pre- or post-release considered as unstable, and both is necessary for API user to review before using or Use at Your Own Risk TM!

I do agree with separating post- and pre-. But, if the addition of feature means minor change in SemVer, then above is an addition IMO, and can be merged soon.

Maybe we can have queue on what major issue (leading to major change) need to be addressed and wait if we are ready for v3.0.0. Then, when v3.0.0 is the next step, just merge them all!

Trivia

I feel SemVer community itself is fear of bumping major version (fear of having v3.0.0). Then, how do the adopters?

Don't take this seriously, except you are agree 😄..

<!-- gh-comment-id:125421794 --> @Abdillah commented on GitHub (Jul 28, 2015): I have some view on this (nightly build). When RAD or Nightly Build is applied, I assume that pre-release is vacum; means the development do not need to use alpha, beta, etc. Is it right @mearns? Then, why don't we propose SemVer to give more freedom on this pre-release "tuple"? I mean instead of specify after a dash is pre-release, SemVer can generalize that it is a tuple representing development stage. It can either pre-release or post-release. But, a project MUST consistent on using it and MUST included explanation on documentation. Moreover, whether pre- or post-release considered as unstable, and both is necessary for API user to review before using or Use at Your Own Risk <sup>TM</sup>! I do agree with separating post- and pre-. But, if the addition of feature means minor change in SemVer, then above is an addition IMO, and can be merged soon. Maybe we can have queue on what major issue (leading to major change) need to be addressed and wait if we are ready for `v3.0.0`. Then, when `v3.0.0` is the next step, just merge them all! #### Trivia I feel SemVer community itself is fear of bumping major version (fear of having `v3.0.0`). Then, how do the adopters? Don't take this seriously, except you are agree :smile:..
Author
Owner

@olivier-spinelli commented on GitHub (Aug 31, 2015):

The contributors of this issue may be interested in http://csemver.org (where C stands for Constrained).
Based on CSemVer, CSemver-CI LastReleasedBased semantic versions de facto support a "Post Release" versionning scheme. I'm having fun designing it, it is totally open to discussion (beta version) and would love to share this beast with anyone interested in this subject.

<!-- gh-comment-id:136429390 --> @olivier-spinelli commented on GitHub (Aug 31, 2015): The contributors of this issue may be interested in http://csemver.org (where C stands for Constrained). Based on CSemVer, CSemver-CI _LastReleasedBased_ semantic versions de facto support a "Post Release" versionning scheme. I'm having fun designing it, it is totally open to discussion (beta version) and would love to share this beast with anyone interested in this subject.
Author
Owner

@mearns commented on GitHub (Aug 31, 2015):

@Abdillah

No, the use of post releases doesn't necessarily mean that pre-releases aren't used. My point is that many agile teams don't know until near the end of the development cycle which changes are going to be included in the next release, so they don't know what the next version number will be.

I don't think just documenting in your code whether you use the field for pre-release or post-release is sufficient. The idea of semvar is that you can understand version numbers the same way across different projects, and write tools that correctly parse them across projects. So if my "post release" field means that it comes after the version, but you use the same field as a "pre release" to indicate that it comes before the version, then the tools won't know what to do.

I've lost track of the conversation, so I don't remember why this was rejected, by my idea was to simply use a different character to indicate whether a suffix is a pre-release or a post release.

Regarding fear of bumping major version: there should be fear. Bumping the major version means you've broken compatibility. Any software that depends on your project is now broken. You should do this as rarely as possible. Ideally, everything would always be major version 1.

<!-- gh-comment-id:136455536 --> @mearns commented on GitHub (Aug 31, 2015): @Abdillah No, the use of post releases doesn't necessarily mean that pre-releases aren't used. My point is that many agile teams don't know until near the end of the development cycle which changes are going to be included in the next release, so they don't know what the next version number will be. I don't think just documenting in your code whether you use the field for pre-release or post-release is sufficient. The idea of semvar is that you can understand version numbers the same way across different projects, and write tools that correctly parse them across projects. So if my "post release" field means that it comes after the version, but you use the same field as a "pre release" to indicate that it comes before the version, then the tools won't know what to do. I've lost track of the conversation, so I don't remember why this was rejected, by my idea was to simply use a different character to indicate whether a suffix is a pre-release or a post release. Regarding fear of bumping major version: there should be fear. Bumping the major version means you've broken compatibility. Any software that depends on your project is now broken. You should do this as rarely as possible. Ideally, everything would always be major version 1.
Author
Owner

@FichteFoll commented on GitHub (Aug 31, 2015):

I've lost track of the conversation, so I don't remember why this was rejected, by my idea was to simply use a different character to indicate whether a suffix is a pre-release or a post release.

I never understood it anyway [the reason for rejection].

It also makes more sense semantically to not use + for "build metadata" but for post-release versioning and instead use something like ~ for the metadata, which I'm still a huge supporter of. It should be clear that this change would require a major bump of the semver spec itself.

<!-- gh-comment-id:136491299 --> @FichteFoll commented on GitHub (Aug 31, 2015): > I've lost track of the conversation, so I don't remember why this was rejected, by my idea was to simply use a different character to indicate whether a suffix is a pre-release or a post release. I never understood it anyway [the reason for rejection]. It also makes more sense semantically to _not_ use `+` for "build metadata" but for post-release versioning and instead use something like `~` for the metadata, which I'm still a huge supporter of. It should be clear that this change would require a major bump of the semver spec itself.
Author
Owner

@judgeaxl commented on GitHub (Oct 26, 2015):

Just some thoughts, as I've been following this for some time, and versioning in general for many years.

As has been mentioned above, a pre-release version can not be counted on to formally follow the rules, in terms of compatibility.

I tend to immediately after a release increment the minor version and attach a pre-release tag, because the next feature release will have to be a minor bump at minimum. In my case, patches are developed on the release branch and automatically get a patch bump, not on the development branch. When it comes time to release, I can make the final decision to keep that minor bump, or go full major, depending on what the changes ended up being.

If a project does publish nightly pre-release builds, then whoever wants to use them need to realize that such a release may be unstable, might not work at all, or change everything. If a team depends on nightly releases of lots of components and this causes problems, then perhaps they need to re-think their approach. If you don't want to expose that kind of uncertainty, then you kind of have to bump the versions and make actual releases instead.

As for internal users, I think they'll just have to look at the changes, or talk to the team, if they absolutely have to work off of the bleeding edge, because any amount of version numbers are not going to solve all possible problems, IMHO.

<!-- gh-comment-id:151017034 --> @judgeaxl commented on GitHub (Oct 26, 2015): Just some thoughts, as I've been following this for some time, and versioning in general for many years. As has been mentioned above, a pre-release version can not be counted on to formally follow the rules, in terms of compatibility. I tend to immediately after a release increment the minor version and attach a pre-release tag, because the next feature release will have to be a minor bump at minimum. In my case, patches are developed on the release branch and automatically get a patch bump, not on the development branch. When it comes time to release, I can make the final decision to keep that minor bump, or go full major, depending on what the changes ended up being. If a project does publish nightly pre-release builds, then whoever wants to use them need to realize that such a release may be unstable, might not work at all, or change everything. If a team depends on nightly releases of lots of components and this causes problems, then perhaps they need to re-think their approach. If you don't want to expose that kind of uncertainty, then you kind of have to bump the versions and make actual releases instead. As for internal users, I think they'll just have to look at the changes, or talk to the team, if they absolutely have to work off of the bleeding edge, because any amount of version numbers are not going to solve all possible problems, IMHO.
Author
Owner

@ygoe commented on GitHub (Nov 26, 2017):

I stopped reading the comments at some point when it started going in circles, sorry for that.

From the first few comments I see two possible solutions:

  • Reinterpret the + as "post-release" instead of metadata. Who needs metadata? This is a version identifier. Descriptive metadata can go in the release notes or marketing materials. This would mean a change to the SemVer spec and considering the + suffix would become mandatory instead of optional. Post-releases then fall into the same class as pre-releases as to suggesting them to a user.
  • Increment the patch number by 1 and use - pre-releases towards that. This is possible today.

I see the problem with the second solution: You still assume version compatibility and temporary incompatible changes would result in unnecessary version increments.

I'd suggest the following change of mind for this: No pre-release is ever "compatible" with anything but itself. Pre-releases are marked as such for a reason. They may contain any kind of changes at any time. Use them only if you know exactly what you get. So I don't care if 1.0.0 or 1.0.1 are in any way compatible with 1.0.1-something. All I care is that 1.0.0 is compatible with 1.0.1.

Is this interpretation acceptable for SemVer?

<!-- gh-comment-id:347012080 --> @ygoe commented on GitHub (Nov 26, 2017): I stopped reading the comments at some point when it started going in circles, sorry for that. From the first few comments I see two possible solutions: * Reinterpret the `+` as "post-release" instead of metadata. Who needs metadata? This is a version identifier. Descriptive metadata can go in the release notes or marketing materials. This would mean a change to the SemVer spec and considering the `+` suffix would become mandatory instead of optional. Post-releases then fall into the same class as pre-releases as to suggesting them to a user. * Increment the patch number by 1 and use `-` pre-releases towards that. This is possible today. I see the problem with the second solution: You still assume version compatibility and temporary incompatible changes would result in unnecessary version increments. I'd suggest the following change of mind for this: No pre-release is ever "compatible" with anything but itself. Pre-releases are marked as such for a reason. They may contain any kind of changes at any time. Use them only if you know exactly what you get. So I don't care if 1.0.0 or 1.0.1 are in any way compatible with 1.0.1-something. All I care is that 1.0.0 is compatible with 1.0.1. Is this interpretation acceptable for SemVer?
Author
Owner

@mearns commented on GitHub (Nov 27, 2017):

In the interest of preserving backwards compatibility for semver, I would support your suggestion (the second bullet) of reinterpreting pre-release to not specify any particular compatibility. I don't think it's the ideal spec, but it is preferable to making incompatible changes to semver.

<!-- gh-comment-id:347054620 --> @mearns commented on GitHub (Nov 27, 2017): In the interest of preserving backwards compatibility for semver, I would support your suggestion (the second bullet) of reinterpreting pre-release to not specify any particular compatibility. I don't think it's the ideal spec, but it is preferable to making incompatible changes to semver.
Author
Owner

@jwdonahue commented on GitHub (Dec 6, 2017):

I think #'s 10 and 11 need to be modified. Rather than calling it build metadata, just call it user-defined data. Whether/how user defined data is applied to precedence is user defined and not covered in the spec. Then users can define their own sort-able, non-sort-able fields and invent whatever semantics they need to have, on top of SemVer.

I also think we need a version meta tag that is defined in a separate standard from SemVer, that can be used to reference specific version schema's that define all of the semantics for a particular version string, whether it's SemVer, Nuget, RPM, etc. It would likely be something that is separated by white space from the version string, and probably should be required to be on the same line. Then SemVer could provide a baseline schema defining its versioning semantics and tool chain makers could add to that to describe the semantics of their user data.

Hope that makes enough sense to get the point across, because I am not ready to present any fleshed out written proposals just yet.

<!-- gh-comment-id:349520301 --> @jwdonahue commented on GitHub (Dec 6, 2017): I think #'s 10 and 11 need to be modified. Rather than calling it build metadata, just call it user-defined data. Whether/how user defined data is applied to precedence is user defined and not covered in the spec. Then users can define their own sort-able, non-sort-able fields and invent whatever semantics they need to have, on top of SemVer. I also think we need a version meta tag that is defined in a separate standard from SemVer, that can be used to reference specific version schema's that define all of the semantics for a particular version string, whether it's SemVer, Nuget, RPM, etc. It would likely be something that is separated by white space from the version string, and probably should be required to be on the same line. Then SemVer could provide a baseline schema defining its versioning semantics and tool chain makers could add to that to describe the semantics of their user data. Hope that makes enough sense to get the point across, because I am not ready to present any fleshed out written proposals just yet.
Author
Owner

@olivier-spinelli commented on GitHub (Dec 6, 2017):

As it has been stated previously in this thread, SemVer is a foundation onto which more elaborated processes, workflows and tools can be built. After a lot of hesitations I choose to embrace it AND build something on it. Two of my main concern were:

  • Nice, automatic and readable handling of "post release" (for the CI builds).
  • Limiting human mistakes by enforcing valid version transitions ("Can a 1.0.1-beta follow a 0.9.0?")

Since I started this work a long ago, one key aspect was that Nuget was not semver compliant: my versions must work with the poor handling of Nuget regarding prerelase part...
I also wanted a correct low-level tagging of my artifacts by using the windows FileVersion in a coherent manner and be able to fix prereleases.

I ended with CSemVer that works great for us. It may interest some of you: http://csemver.org/ (do not hesitate to test the playground :)).

An implementation is available here: https://github.com/SimpleGitVersion/CSemVer-Net that contains a parsers for SVersion (SemVer) and CSVersion (for CSemVer versions) with all the Predecessors/Successors computations.

<!-- gh-comment-id:349591344 --> @olivier-spinelli commented on GitHub (Dec 6, 2017): As it has been stated previously in this thread, SemVer is a foundation onto which more elaborated processes, workflows and tools can be built. After a lot of hesitations I choose to embrace it AND build something on it. Two of my main concern were: - Nice, automatic and readable handling of "post release" (for the CI builds). - Limiting human mistakes by enforcing valid version transitions ("Can a 1.0.1-beta follow a 0.9.0?") Since I started this work a long ago, one key aspect was that Nuget was not semver compliant: my versions must work with the poor handling of Nuget regarding prerelase part... I also wanted a correct low-level tagging of my artifacts by using the windows FileVersion in a coherent manner and be able to fix prereleases. I ended with CSemVer that works great for us. It may interest some of you: http://csemver.org/ (do not hesitate to test the playground :)). An implementation is available here: https://github.com/SimpleGitVersion/CSemVer-Net that contains a parsers for SVersion (SemVer) and CSVersion (for CSemVer versions) with all the Predecessors/Successors computations.
Author
Owner

@ygoe commented on GitHub (Dec 8, 2017):

That CSemVer looks overly complicated to me. I don't think I'll ever see the need for that.

<!-- gh-comment-id:350358637 --> @ygoe commented on GitHub (Dec 8, 2017): That CSemVer looks overly complicated to me. I don't think I'll ever see the need for that.
Author
Owner

@mentalisttraceur commented on GitHub (Aug 17, 2018):

Been fighting with this a bit in my own work lately, and thinking about this a lot. I suggest the following approach, which just discards the idea of trying to bend SemVer to fit CI builds:

  1. When possible, SemVer is just not used for development/nightly builds where the actual future release number is not yet determinable for sure.

  2. When not possible, drop version to a 0.0.0 pre-release. SemVer's clause about there not being backward compatibility guarantees in major version 0 serves as an escape hatch, and the intentionally lower-than-any-real-release sorting has the advantage that a user has to know what they're doing and explicitly require your not-really-an-actual-official-release version.

Some people above apparently want their development builds to explicitly sort above their extant releases, and I can understand why that can be useful in some cases, like purely internal testing depending on automatic "get latest" behavior, where it doesn't matter how much you break SemVer.

It is in the releases to the external world that SemVer matters, and there, users almost never want to be able to accidentally upgrade to your development builds, and if they do, then by all rights it ought to be an official release.

(Incidentally, it looks like @olivier-spinelli had the same idea as my point 2 above, with the CSemVer-CI zero-based concept.)

Key point: SemVer signals "pay attention" information to those who depend on your software - with normal releases you can break that "pay attention" signaling into semantically meaningful numbers. We can't meaningfully segment the sort of arbitrary and unpredictable changes that arise in development work that hasn't yet made the cut into a release yet.

<!-- gh-comment-id:414000486 --> @mentalisttraceur commented on GitHub (Aug 17, 2018): Been fighting with this a bit in my own work lately, and thinking about this a lot. I suggest the following approach, which just **discards** the idea of trying to bend SemVer to fit CI builds: 1. When possible, SemVer is just **not used** for development/nightly builds where the actual future release number is not yet determinable for sure. 2. When not possible, *drop version to a 0.0.0 **pre-release***. SemVer's clause about there not being backward compatibility guarantees in major version 0 serves as an escape hatch, and the intentionally lower-than-any-real-release sorting has the advantage that a user has to know what they're doing and explicitly require your not-really-an-actual-official-release version. Some people above apparently want their development builds to explicitly sort above their extant releases, and I can understand why that can be useful in some cases, like purely internal testing depending on automatic "get latest" behavior, where it doesn't matter how much you break SemVer. It is in the releases to the external world that SemVer matters, and there, users almost never want to be able to *accidentally* upgrade to your *development* builds, and if they do, then by all rights it *ought to be* an official release. (Incidentally, it looks like @olivier-spinelli had the same idea as my point 2 above, with the CSemVer-CI zero-based concept.) Key point: SemVer signals "pay attention" information to those who depend on your software - with normal releases you can break that "pay attention" signaling into semantically meaningful numbers. We can't meaningfully segment the sort of *arbitrary and unpredictable* changes that arise in development work that hasn't yet made the cut into a release yet.
Author
Owner

@jwdonahue commented on GitHub (Aug 18, 2018):

@mearns, -dev is poor choice for CI builds. -alpha < -beta < -dev, probably not what you want, so you have to do something like -a.dev < -alpha < -beta.

It seems that some of the folks on this thread have come to the erroneous conclusion that a "release" is a package with a non-prerelease version string (ie; 1.0.0, 1.0.0+buildmeta) and that the prerelease tag is only useful before a "release". This not what is meant by the English word "release" or the spec. A release is anything that is publicly available, no matter what tags it has on it. By "publicly available" I mean; available in its fully packaged form across a network connection (including sneaker-nets!). I wish the spec used the term "published" instead.

Every published package must have a unique version string attached. As some have pointed out, a prerelease tag loosens the compatibility constraints on the version triple. This enables CI builds to simply bump the patch number on each build and apply a prerelease tag indicating the product may be unstable. I always use something along the lines of -a.dev+branch for CI builds. Then "release builds", or rather official stable releases can be selected from a set of recent CI builds and repackaged with the appropriate non-prerelease version triple, based on the content of that release.

You get histories with parallel release trains like this:

0.1.0-a.dev+feat1  // First feature.
  // PubInt pulls from feat1
  1.0.0-a.flight1+PubInt // Internal adopters.
  1.0.0-a.flight2+PubInt// Wider audience.
    // PubExt pulls from PubInt
    1.0.0-alpha+PubExt // External early adopters.
0.1.1-a.dev+feat1 // Bug fix.
  // PubInt pulls fix from feat1
  1.0.1-a.flight1+PubInt 
    // Oops! hot fix needed everywhere, no time/need for flight2.
    // PubExt pulls from PubInt
    1.0.1-alpha+PubExt
1.1.0-a.dev+feat2 // Work begins on the next feature.
    // Feedback from alpha customers is good.
    1.0.1-beta+PubExt // Wider audience.
    // Feed back from beta customers is good.
    1.0.1+PubExt // First stable release.
// Mean while, work continues in feat2
1.1.0-a.dev+feat2 // WIP
1.1.1-a.dev+feat2 // WIP
  // PubInt pulls from feat2
  1.1.1-a.flight1+PubInt
1.1.3--a.dev+feat2 // WIP
  // PubInt pulls from feat2
  1.1.3-a.flight1+PubInt
    // PubExt pulls from PubInt
    1.1.3-alpha+PubExt
    1.1.3-beta+PubExt
    1.1.3+PubExt // Second stable release.
...

One useful technique is for CI builds to release packages that include the branch in the package name:

XRay.Feat1 0.1.0-a.dev+buildmeta // Available to dev/test only.
XRay.PubInt 0.1.0-a.flight1+buildmeta // Available to internal dog-food eaters.
XRay 1.0.0 // PubExt uses just the product name in packaging.

This can be very helpful when you have multiple parallel feature branches:

XRay.origin 0.0.y-a.dev // Primed with minimal common content.
XRay.feat1 0.1.0-a.dev+origin // feat1 derives from origin.
XRay.feat2 0.1.0-a.dev+origin // feat2 derives from origin.
XRay.feat3 0.1.0-a.dev+feat1  // feat3 derives from feat1.
XRay.feat4 0.1.0-a.dev+feat2  // feat4 derives from feat2.
// Origin merges feat1
XRay.origin 0.1.0-a.dev
// Origin merges Feat4
XRay.origin 0.2.0-a.dev
...

In this scenario, PubInt and PubExt would pull from origin. None of the feature branches need have any knowledge of the published package version history, they simply maintain their own version history and their packages never collide with versions from other branches.

The semver scheme could not work with just a postrelease tag, so you'd have to have both if had postrelease, but you can easily get by with just the prerelease tag and that's why semver has one.

@mearns, it's unlikely that any new tags or fields will be accepted into the semver spec. There have been other post-release proposals that have died on the vine. Unless you intend to issue a PR for whatever changes you have in mind or you have additional questions, please close this thread at your earliest possible convenience.

<!-- gh-comment-id:414027802 --> @jwdonahue commented on GitHub (Aug 18, 2018): @mearns, -dev is poor choice for CI builds. -alpha < -beta < -dev, probably not what you want, so you have to do something like -a.dev < -alpha < -beta. It seems that some of the folks on this thread have come to the erroneous conclusion that a "release" is a package with a non-prerelease version string (ie; 1.0.0, 1.0.0+buildmeta) and that the prerelease tag is only useful _before_ a "release". This not what is meant by the English word "release" or the spec. A release is anything that is publicly available, no matter what tags it has on it. By "publicly available" I mean; available in its fully packaged form across a network connection (including sneaker-nets!). I wish the spec used the term "published" instead. Every published package must have a unique version string attached. As some have pointed out, a prerelease tag loosens the compatibility constraints on the version triple. This enables CI builds to simply bump the patch number on each build and apply a prerelease tag indicating the product may be unstable. I always use something along the lines of -a.dev+branch for CI builds. Then "release builds", or rather official stable releases can be selected from a set of recent CI builds and repackaged with the appropriate non-prerelease version triple, based on the content of that release. You get histories with parallel release trains like this: ``` 0.1.0-a.dev+feat1 // First feature. // PubInt pulls from feat1 1.0.0-a.flight1+PubInt // Internal adopters. 1.0.0-a.flight2+PubInt// Wider audience. // PubExt pulls from PubInt 1.0.0-alpha+PubExt // External early adopters. 0.1.1-a.dev+feat1 // Bug fix. // PubInt pulls fix from feat1 1.0.1-a.flight1+PubInt // Oops! hot fix needed everywhere, no time/need for flight2. // PubExt pulls from PubInt 1.0.1-alpha+PubExt 1.1.0-a.dev+feat2 // Work begins on the next feature. // Feedback from alpha customers is good. 1.0.1-beta+PubExt // Wider audience. // Feed back from beta customers is good. 1.0.1+PubExt // First stable release. // Mean while, work continues in feat2 1.1.0-a.dev+feat2 // WIP 1.1.1-a.dev+feat2 // WIP // PubInt pulls from feat2 1.1.1-a.flight1+PubInt 1.1.3--a.dev+feat2 // WIP // PubInt pulls from feat2 1.1.3-a.flight1+PubInt // PubExt pulls from PubInt 1.1.3-alpha+PubExt 1.1.3-beta+PubExt 1.1.3+PubExt // Second stable release. ... ``` One useful technique is for CI builds to release packages that include the branch in the package name: ``` XRay.Feat1 0.1.0-a.dev+buildmeta // Available to dev/test only. XRay.PubInt 0.1.0-a.flight1+buildmeta // Available to internal dog-food eaters. XRay 1.0.0 // PubExt uses just the product name in packaging. ``` This can be very helpful when you have multiple parallel feature branches: ``` XRay.origin 0.0.y-a.dev // Primed with minimal common content. XRay.feat1 0.1.0-a.dev+origin // feat1 derives from origin. XRay.feat2 0.1.0-a.dev+origin // feat2 derives from origin. XRay.feat3 0.1.0-a.dev+feat1 // feat3 derives from feat1. XRay.feat4 0.1.0-a.dev+feat2 // feat4 derives from feat2. // Origin merges feat1 XRay.origin 0.1.0-a.dev // Origin merges Feat4 XRay.origin 0.2.0-a.dev ... ``` In this scenario, PubInt and PubExt would pull from origin. None of the feature branches need have any knowledge of the published package version history, they simply maintain their own version history and their packages never collide with versions from other branches. The semver scheme could not work with just a postrelease tag, so you'd have to have both if had postrelease, but you can easily get by with just the prerelease tag and that's why semver has one. @mearns, it's unlikely that any new tags or fields will be accepted into the semver spec. There have been other post-release proposals that have died on the vine. Unless you intend to issue a PR for whatever changes you have in mind or you have additional questions, please close this thread at your earliest possible convenience.
Author
Owner

@olivier-spinelli commented on GitHub (Aug 19, 2018):

It seems to me that the issue is about "post-release" builds. SemVer handles "pre-release" but not "post-release". I wanted post-release support and a safe resolution of versions. My answer has been:

  • First: to define a subset of SemVer with standardized versions (called CSemVer versions). No more "2.0.0-final" that is BEFORE "2.0.0-update"!
  • Second: based on this perfectly defined possible versions, "inject" -CI versions into them in a way that the SemVer ordering rules guaranty an absolute ordering of all the kind of versions

CI versions are necessarily after their base (the last CSemVer version) and before any possible future CSemVer version.
There is no graph/tree (except if you use different suffixes for different branches of CI versions). Only a totally ordered (unambiguous) set of versions that will safely be handled by any package manager.

There are more things in CSemVer but, at least, it gives me the "post-release" semantic I needed.

For whom it may interest, it's here: http://csemver.org (git page).

<!-- gh-comment-id:414109422 --> @olivier-spinelli commented on GitHub (Aug 19, 2018): It seems to me that the issue is about "post-release" builds. SemVer handles "pre-release" but not "post-release". I wanted post-release support and a safe resolution of versions. My answer has been: - First: to define a subset of SemVer with standardized versions (called CSemVer versions). No more "2.0.0-final" that is BEFORE "2.0.0-update"! - Second: based on this perfectly defined possible versions, "inject" -CI versions into them in a way that the SemVer ordering rules guaranty an absolute ordering of all the kind of versions CI versions are necessarily after their base (the last CSemVer version) and before any possible future CSemVer version. There is no graph/tree (except if you use different suffixes for different branches of CI versions). Only a totally ordered (unambiguous) set of versions that will safely be handled by any package manager. There are more things in CSemVer but, at least, it gives me the "post-release" semantic I needed. For whom it may interest, it's here: http://csemver.org (git page).
Author
Owner

@jwdonahue commented on GitHub (Aug 19, 2018):

@olivier-spinelli, it's another way to do things. The real problem is how to communicate the syntax, semantics and related processes that cause a specific release in a way that machines and humans can reason over. See https://versionmeta.org. It's still a work in progress. Good weather has kept me away from my machine the past few months.

<!-- gh-comment-id:414134506 --> @jwdonahue commented on GitHub (Aug 19, 2018): @olivier-spinelli, it's another way to do things. The real problem is how to communicate the syntax, semantics and related processes that cause a specific release in a way that machines and humans can reason over. See [https://versionmeta.org](https://versionmeta.org). It's still a work in progress. Good weather has kept me away from my machine the past few months.
Author
Owner

@judgeaxl commented on GitHub (Aug 20, 2018):

@olivier-spinelli, just out of curiosity, what, in your opinion, is the difference between a "post-release" build and a "pre-release" build, assuming all branches may eventually converge into a release? I.e. is a build after 1.0.0 a post-release build of 1.0.0 or a pre-release build of 1.0.1 (or 1.1.0)? When would it change from one to the other?

I've been experimenting with using the -alpha pre-release for dev builds, with meta data for branches and features attached. Develop builds are always a minor version higher than the last release branch, unless I explicitly say it's a major increment. Release builds are always -beta until they get released. Hot fix branches off of each release (or commits on the release branch post the actual release tag) always have a patch version increment and a -beta pre-release. This has worked well enough not to warrant any amendments to SemVer so far.

I also consider any -alpha build to essentially have the same semantics as a 0.0.0 build, i.e. anything can be broken or incompatible for an arbitrary length of time. SemVer restrictions are not enforced until before the next release branch is created, or someone complains loudly enough.

I'm primarily developing libraries, frameworks, and packaged apps, so I've not tried this with any sort of continuous service deployment.

<!-- gh-comment-id:414177366 --> @judgeaxl commented on GitHub (Aug 20, 2018): @olivier-spinelli, just out of curiosity, what, in your opinion, is the difference between a "post-release" build and a "pre-release" build, assuming all branches may eventually converge into a release? I.e. is a build after 1.0.0 a post-release build of 1.0.0 or a pre-release build of 1.0.1 (or 1.1.0)? When would it change from one to the other? I've been experimenting with using the `-alpha` pre-release for dev builds, with meta data for branches and features attached. Develop builds are always a minor version higher than the last release branch, unless I explicitly say it's a major increment. Release builds are always `-beta` until they get released. Hot fix branches off of each release (or commits on the release branch post the actual release tag) always have a patch version increment and a `-beta` pre-release. This has worked well enough not to warrant any amendments to SemVer so far. I also consider any `-alpha` build to essentially have the same semantics as a `0.0.0` build, i.e. anything can be broken or incompatible for an arbitrary length of time. SemVer restrictions are not enforced until before the next release branch is created, or someone complains loudly enough. I'm primarily developing libraries, frameworks, and packaged apps, so I've not tried this with any sort of continuous service deployment.
Author
Owner

@olivier-spinelli commented on GitHub (Aug 21, 2018):

@jwdonahue, you're right, it's all about semantics to the developers (meaning actual devs but also sysops, maintainers, etc.). This is why I wanted the published versions to be fundamentally unambiguous, based on total order.

<!-- gh-comment-id:414565751 --> @olivier-spinelli commented on GitHub (Aug 21, 2018): @jwdonahue, you're right, it's all about semantics **to the developers** (meaning actual devs but also sysops, maintainers, etc.). This is why I wanted the published versions to be fundamentally unambiguous, based on total order.
Author
Owner

@olivier-spinelli commented on GitHub (Aug 21, 2018):

@judgeaxl, I tried using a more relaxed scheme as yours with (hopefully orthogonal) features in different packages. I stopped and converged to this very simple linear model.

To directly answer your question: a post-release build is a CI-build. There is no human involved in the process since there is no "actual version" to set. The only thing we know is that the component/artifact is the 4th after the 2.0.1-rc... However, technically, it is a fully valid artifact that can be consumed by any other Solutions that uses it.
Actual releases, the one where a human (potentially helped by tools that try to detect breaking changes/evolutions/fix) has to choose a version are manually triggered at any time and they can be "Pre-Release" (alpha, beta, etc.) as well as "Official Release".

(Side note about automated tools: I don't believe in any tool that will decide on its own whether the major/minor/patch has to be incremented, they only can prevent/signal some obvious changes and prevent human mistakes.)

<!-- gh-comment-id:414568818 --> @olivier-spinelli commented on GitHub (Aug 21, 2018): @judgeaxl, I tried using a more relaxed scheme as yours with (hopefully orthogonal) features in different packages. I stopped and converged to this very simple linear model. To directly answer your question: a post-release build is a CI-build. There is no human involved in the process since there is no "actual version" to set. The only thing we know is that the component/artifact is the 4th after the 2.0.1-rc... However, technically, it is a fully valid artifact that can be consumed by any other Solutions that uses it. Actual releases, the one where a human (potentially helped by tools that try to detect breaking changes/evolutions/fix) has to choose a version are manually triggered at any time and they can be "Pre-Release" (alpha, beta, etc.) as well as "Official Release". (Side note about automated tools: I don't believe in any tool that will decide on its own whether the major/minor/patch has to be incremented, they only can prevent/signal some obvious changes and prevent human mistakes.)
Author
Owner

@jwdonahue commented on GitHub (Aug 21, 2018):

@olivier-spinelli, take a look at https://versionmeta.org and http://versionschema.org (finally published the first version). I suspect we could define your csemver using version schema. VersionSchema has some potential advantages over SemVer and other schemes because it should be able to unambiguously define virtually any scheme. Well that's the goal anyway, I am sure it needs a lot of work. It also needs some tooling and I am working on that now, as the fires around here have rendered the out-doors unfit for life.

<!-- gh-comment-id:414710341 --> @jwdonahue commented on GitHub (Aug 21, 2018): @olivier-spinelli, take a look at https://versionmeta.org and http://versionschema.org (finally published the first version). I suspect we could define your csemver using version schema. VersionSchema has some potential advantages over SemVer and other schemes because it should be able to unambiguously define virtually any scheme. Well that's the goal anyway, I am sure it needs a lot of work. It also needs some tooling and I am working on that now, as the fires around here have rendered the out-doors unfit for life.
Author
Owner

@jwdonahue commented on GitHub (Oct 8, 2018):

@mearns, unless you intend to issue a PR or have further comments/questions, please close this thread at your earliest possible convenience. I don't see this idea getting any traction here. You might want to follow the links I posted in my previous message of @olivier-spinelli. I am proposing a standard way to define version strings that incorporates more information about regarding the logic used to generate those strings. Working on tooling. Got a long way to go. Input from potential adopters would be useful.

<!-- gh-comment-id:427715488 --> @jwdonahue commented on GitHub (Oct 8, 2018): @mearns, unless you intend to issue a PR or have further comments/questions, please close this thread at your earliest possible convenience. I don't see this idea getting any traction here. You might want to follow the links I posted in my previous message of @olivier-spinelli. I am proposing a standard way to define version strings that incorporates more information about regarding the logic used to generate those strings. Working on tooling. Got a long way to go. Input from potential adopters would be useful.
Author
Owner

@chindraba-work commented on GitHub (Mar 21, 2019):

@mearns As written in SemVer 2.0.0, your use of nightly builds, or any other frequency, are handled perfectly. The only "problem" is that they are not post-release, they are pre-release.

If you have just released version 2.5.1 (however it was released, and to what ever audience it was released), your next work is not on 2.5.1-dev, but on 2.5.2-dev. Yes, I do know that at the point of issuing the new version number you do not know if it will be a patch-level, minor-level, or major-level change. The SemVer spec, recognized that possibility.

Section 9, which covers the pre-release specifically covers the possibility that the changes might be "breaking"

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.

Since the pre-release version is a series of dot separated identifiers of unbounded length (unbounded in the spec anyway, not necessarily unbounded in-house) the method used can include a timestamp and a developer ID as well, if needed. you could be working on 2.5.2-dev.mearns-20190321T051051 while I am working on 2.5.2-dev.chindraba-20190321T051223. Your version could even have a breaking change to the public API and mine could have new non-breaking changes to the API. Tomorrow your version 2.5.2-dev.mearns-20190321T211539 could revert those changes and merge mine. At no point in any of the development is the leading version number 2.5.2 being changed, nor does it need to be. As a pre-release it is allowed for the current build to break anything and everything in the API without violating the rules of SymVer.

When the pre-release version is ready to become a release, then the version number can be set as appropriate: If the API has any breaking change, it becomes 3.0.0. If the API has non-breaking changes, then the new release is 2.6.0. If neither applies, then it is 2.5.2. In any of the three cases, the next development cycle would be numbered as the next patch-level from the just released version (3.0.1-dev, 2.6.1-dev, or 2.5.3-dev).

Now, for the idea that the "release" of your build, nightly or whenever, being the point that it leaves your computer, such as going to the QA team, or the rest of your dev team. What you are working on can be in either of two positions, non-exclusively: top-level element or a dependency. In both cases, if you have induced any API changes, breaking or not, your statement about the QA team is incorrect.

The QA team can automatically decide which tests to run based on the version because they can tell how it effected the API.

If you make API-level changes, breaking or not, the QA team will have no idea what tests to run because they will not have the new API information available until you provide it to them. If it is a non-breaking new feature, you will have to tell them what that feature is, what it's API spec (interface?) is and what it is supposed to do. If it is a breaking change, you need to tell them what the new version of the API spec is, and how it is different in either the interface or the results. A new minor, or major, version number will not convey that data. The most that they would know from the new version numbers is that there is some change somewhere and they have to find out what that is from you. Outside the QA team the exact same problem occurs: without your input nobody knows what you've done to the API, if anything.

If the project is a top-level element (such as a browser, or command line tool) then, hopefully, it works when you commit it (or do whatever you do to "release" it from your computer), and changes in the API are changes in how it is used or invoked, and those with access to it have been advised that there might be changes by the mere fact that it is a pre-release, nightly build, snapshot, or whatever. Anyone who chooses to use, or rely on, such a release should know that it might be different than it was last time.

If the project is a dependency (which could still be a top-level element as well), then it should not be used outside of a testing environment. The pre-release version tag after the standard version number should prevent it from being automatically updated to, and any developers choosing to use it in the pre-release form has been advised that it is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version as stated by the SemVer spec.

Disclaimer: I'm not, yet, a user of SemVer, let alone a fan, and I have not done Agile, Extreme Programming, or even TDD, as all my development has been done the way I became accustomed to doing it before such things were invented. (Before the Internet was invented as well.)

As I've given at least 2 cents worth, I won't be surprised to be given some change. :)

<!-- gh-comment-id:475121843 --> @chindraba-work commented on GitHub (Mar 21, 2019): @mearns As written in SemVer 2.0.0, your use of nightly builds, or any other frequency, are handled perfectly. The only "problem" is that they are not post-release, they are pre-release. If you have just released version 2.5.1 (however it was released, and to what ever audience it was released), your next work is not on 2.5.1-dev, but on 2.5.2-dev. Yes, I do know that at the point of issuing the new version number you do not know if it will be a patch-level, minor-level, or major-level change. The SemVer spec, recognized that possibility. [Section 9](https://semver.org/#spec-item-9), which covers the pre-release specifically covers the possibility that the changes might be "breaking" > 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. Since the pre-release version is a series of dot separated identifiers of unbounded length (unbounded in the spec anyway, not necessarily unbounded in-house) the method used can include a timestamp and a developer ID as well, if needed. you could be working on `2.5.2-dev.mearns-20190321T051051` while I am working on `2.5.2-dev.chindraba-20190321T051223`. Your version could even have a breaking change to the public API and mine could have new non-breaking changes to the API. Tomorrow your version `2.5.2-dev.mearns-20190321T211539` could revert those changes and merge mine. At no point in any of the development is the leading version number `2.5.2` being changed, nor does it need to be. As a pre-release it is allowed for the current build to break _anything_ and _everything_ in the API without violating the rules of SymVer. When the pre-release version is ready to become a release, then the version number can be set as appropriate: If the API has _any_ breaking change, it becomes 3.0.0. If the API has non-breaking changes, then the new release is 2.6.0. If neither applies, then it is 2.5.2. In any of the three cases, the next development cycle would be numbered as the next patch-level from the just released version (3.0.1-dev, 2.6.1-dev, or 2.5.3-dev). Now, for the idea that the "release" of your build, nightly or whenever, being the point that it leaves your computer, such as going to the QA team, or the rest of your dev team. What you are working on can be in either of two positions, non-exclusively: top-level element or a dependency. In both cases, if you have induced any API changes, breaking or not, your statement about the QA team is incorrect. > The QA team can automatically decide which tests to run based on the version because they can tell how it effected the API. If you make API-level changes, breaking or not, the QA team will have no idea what tests to run because they will not have the new API information available until you provide it to them. If it is a non-breaking new feature, you will have to tell them what that feature is, what it's API spec (interface?) is and what it is supposed to do. If it is a breaking change, you need to tell them what the new version of the API spec is, and how it is different in either the interface or the results. A new minor, or major, version number will not convey that data. The most that they would know from the new version numbers is that there is _some_ change _somewhere_ and they have to find out what that is from you. Outside the QA team the exact same problem occurs: without your input nobody knows what you've done to the API, if anything. If the project is a top-level element (such as a browser, or command line tool) then, hopefully, it works when you commit it (or do whatever you do to "release" it from your computer), and changes in the API are changes in how it is used or invoked, and those with access to it have been advised that there _might be_ changes by the mere fact that it is a pre-release, nightly build, snapshot, or whatever. Anyone who chooses to use, or rely on, such a release should know that it might be different than it was last time. If the project is a dependency (which could still be a top-level element as well), then it should _not_ be used outside of a testing environment. The pre-release version tag after the standard version number should prevent it from being automatically updated to, and any developers choosing to use it in the pre-release form has been advised that it is _unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version_ as stated by the SemVer spec. _Disclaimer_: I'm not, yet, a user of SemVer, let alone a fan, and I have not done Agile, Extreme Programming, or even TDD, as all my development has been done the way I became accustomed to doing it before such things were invented. (Before the Internet was invented as well.) As I've given at least 2 cents worth, I won't be surprised to be given some change. :)
Author
Owner

@alexandrtovmach commented on GitHub (Jun 10, 2020):

Thanks everyone for contributions, you're amazing 🎆 Did you find any consensus?

<!-- gh-comment-id:642133646 --> @alexandrtovmach commented on GitHub (Jun 10, 2020): Thanks everyone for contributions, you're amazing :fireworks: Did you find any consensus?
Author
Owner

@ljharb commented on GitHub (Jun 10, 2020):

The next nightly should just be a prerelease. If you don't know what version it'll be, make it a patch prerelease. once you know it's a minor or a major, make it a prerelease of that.

<!-- gh-comment-id:642177675 --> @ljharb commented on GitHub (Jun 10, 2020): The next nightly should just be a prerelease. If you don't know what version it'll be, make it a patch prerelease. once you know it's a minor or a major, make it a prerelease of that.
Author
Owner

@olivier-spinelli commented on GitHub (Jun 11, 2020):

@alexandrtovmach I don't get the "consensus" idea here. About what?
SemVer handles pre-release. Handling post release is possible as long as you constrain a little bit the possible versions of SemVer. This is what https://csemver.org does:

CSemVer-CI is an extension that supports CI builds. Its versions follow SemVer 2.0.0, but are not CSemVer compliant. CSemVer-CI defines 2 kind of CI versions:

  • ZeroBased
    Versions are based on the 0.0.0 very first version and are smaller than it. Any version of this kind has always a lower precedence than any version of actual releases.
  • LastReleasedBased
    Versions are based on a previous release. They are greater than their base version but always lower than any successor of their base.
<!-- gh-comment-id:642579361 --> @olivier-spinelli commented on GitHub (Jun 11, 2020): @alexandrtovmach I don't get the "consensus" idea here. About what? SemVer handles pre-release. Handling post release is possible as long as you constrain a little bit the possible versions of SemVer. This is what https://csemver.org does: > CSemVer-CI is an extension that supports CI builds. Its versions follow SemVer 2.0.0, but are not CSemVer compliant. CSemVer-CI defines 2 kind of CI versions: > > - ZeroBased > Versions are based on the 0.0.0 very first version and are smaller than it. Any version of this kind has always a lower precedence than any version of actual releases. > - LastReleasedBased > Versions are based on a previous release. They are greater than their base version but always lower than any successor of their base.
Author
Owner

@mentalisttraceur commented on GitHub (Jun 11, 2020):

@alexandrtovmach I think there is some consensus forming towards "if you really need nightly builds to use SemVer, then if there are no actual guarantees about what the public API is, use a 0.0.0 pre-release, otherwise, just use a regular pre-release (but if you don't release your development/nightly builds to the same channel that updates to official finalized releases are regularly installed from, you can just break SemVer, and maybe you should reevaluate if SemVer is actually right for this use case)".

But you will never have overwhelming consensus while SemVer remains dominantly popular, because there are always going to be people who want to shove more features into something, and other people who will assert that those features are unnecessary and symptoms of doing or wanting something else wrongly.

One of the biggest challenges and responsibilities of a maintainer is knowing when to say no to features despite diligently and compassionately considering the desires and reasons for them, and even as users are actively asking for them. Because with a popular project, you'll be getting a lot of people wanting things just because it solves the problem they have as they have conceptualized it.

But I do encourage anyone still looking for a solution to SemVer with nightly builds and not satisfied with anything else said here to ask themselves if anything I said in this comment I just made on another issue would address that.

<!-- gh-comment-id:642905449 --> @mentalisttraceur commented on GitHub (Jun 11, 2020): @alexandrtovmach I think there is *some* consensus forming towards "if you really need nightly builds to use SemVer, then if there are no actual guarantees about what the public API is, use a `0.0.0` pre-release, otherwise, just use a regular pre-release (but if you don't release your development/nightly builds to the same channel that updates to official finalized releases are regularly installed from, you can just break SemVer, and maybe you should reevaluate if SemVer is actually right for this use case)". But you will never have overwhelming consensus while SemVer remains dominantly popular, because there are always going to be people who want to shove more features into something, and other people who will assert that those features are unnecessary and symptoms of doing or wanting something else wrongly. One of the biggest challenges and responsibilities of a maintainer is knowing when to say no to features despite diligently and compassionately considering the desires and reasons for them, and even as users are actively asking for them. Because with a popular project, you'll be getting a lot of people wanting things just because it solves the problem they have *as they have conceptualized it*. But I do encourage anyone still looking for a solution to SemVer with nightly builds and not satisfied with anything else said here to ask themselves if anything I said in [this comment I just made on another issue](https://github.com/semver/semver/pull/519#issuecomment-642887824) would address that.
Author
Owner

@ygoe commented on GitHub (Jun 11, 2020):

I also have the impression that "pre-release of the next patch version" seems to be the way that's most suggested and accepted here. I'm using that practice for a while now and so far it looks successful. From my previous comment, I'd have one suggestion to that to make it less dangerous:

I'd suggest the following change of mind for this: No pre-release is ever "compatible" with anything but itself. Pre-releases are marked as such for a reason. They may contain any kind of changes at any time. Use them only if you know exactly what you get. So I don't care if 1.0.0 or 1.0.1 are in any way compatible with 1.0.1-something. All I care is that 1.0.0 is compatible with 1.0.1.

As an addition to my earlier statement, I found the metadata to be useful to keep the Git commit hash directly in the version identifier. That makes it easier to find the code that's running if it's not directly tagged as a release. My versioning tool can add the number of commits since the last version tag, but having the commit hash is easier than counting commits along a branch line.

<!-- gh-comment-id:642926544 --> @ygoe commented on GitHub (Jun 11, 2020): I also have the impression that "pre-release of the next patch version" seems to be the way that's most suggested and accepted here. I'm using that practice for a while now and so far it looks successful. From [my previous comment](https://github.com/semver/semver/issues/200#issuecomment-347012080), I'd have one suggestion to that to make it less dangerous: > I'd suggest the following change of mind for this: No pre-release is ever "compatible" with anything but itself. Pre-releases are marked as such for a reason. They may contain any kind of changes at any time. Use them only if you know exactly what you get. So I don't care if 1.0.0 or 1.0.1 are in any way compatible with 1.0.1-something. All I care is that 1.0.0 is compatible with 1.0.1. As an addition to my earlier statement, I found the metadata to be useful to keep the Git commit hash directly in the version identifier. That makes it easier to find the code that's running if it's not directly tagged as a release. My [versioning tool](https://github.com/ygoe/NetRevisionTask) can add the number of commits since the last version tag, but having the commit hash is easier than counting commits along a branch line.
Author
Owner

@FichteFoll commented on GitHub (Jun 14, 2020):

Regardless of what is the best currently available workaround, I believe it should be discussed whether this ability should be added to SemVer and if yes, how. I don't think we are at the point in the discussion where we have reached consensus on how to proceed with the proposal.
For example, If the consensus was "this problem doesn't need solving by SemVer because that only governs outward-facing releases and not internal dev releases", then this would be a reason to close and dismuss the issue. Extensions of semver to provide the desired feature or the pre-release shenanigan workaround can be used.

However, reality speaks that there are many systems out there that provide or utilize automated CI builds and that have no common ground for specifying versions for their artifacts and SemVer could step in to fill that void, especially given how popular it is.

I would also like to see a usage study of build metadata for considering whether to allow using that for determining precedence again.

<!-- gh-comment-id:643751090 --> @FichteFoll commented on GitHub (Jun 14, 2020): Regardless of what is the best currently available workaround, I believe it should be discussed whether this ability should be added to SemVer and if yes, how. I don't think we are at the point in the discussion where we have reached consensus on how to proceed with the proposal. For example, If the consensus was "this problem doesn't need solving by SemVer because that only governs outward-facing releases and not internal dev releases", then this would be a reason to close and dismuss the issue. Extensions of semver to provide the desired feature or the pre-release shenanigan workaround can be used. However, reality speaks that there are *many* systems out there that provide or utilize automated CI builds and that have no common ground for specifying versions for their artifacts and SemVer *could* step in to fill that void, especially given how popular it is. I would also like to see a usage study of build metadata for considering whether to allow using that for determining precedence again.
Author
Owner

@steveklabnik commented on GitHub (Jun 14, 2020):

I personally think this is all handled just fine by the spec as is, and doesn't need to be changed.

<!-- gh-comment-id:643766414 --> @steveklabnik commented on GitHub (Jun 14, 2020): I personally think this is all handled just fine by the spec as is, and doesn't need to be changed.
Author
Owner

@vcorr commented on GitHub (Sep 11, 2020):

I'd like to clarify one more thing

@ygoe

I also have the impression that "pre-release of the next patch version" seems to be the way that's most suggested and accepted here. I'm using that practice for a while now and so far it looks successful.

Assume that your latest release is 1.2.0 and it's deployed to production. Then you begin working on 1.2.1-dev or whatever postfix you prefer. You add new features and perhaps even breaking changes. Then a bug is found in production and needs to be patched asap. The sensible version for that bug fix would be 1.2.1. If you deliver that version (obviously from your release branch, including nothing but the bug fix), what happens to your development version number after that?

<!-- gh-comment-id:690895826 --> @vcorr commented on GitHub (Sep 11, 2020): I'd like to clarify one more thing @ygoe > I also have the impression that "pre-release of the next patch version" seems to be the way that's most suggested and accepted here. I'm using that practice for a while now and so far it looks successful. Assume that your latest release is 1.2.0 and it's deployed to production. Then you begin working on 1.2.1-dev or whatever postfix you prefer. You add new features and perhaps even breaking changes. Then a bug is found in production and needs to be patched asap. The sensible version for that bug fix would be 1.2.1. If you deliver that version (obviously from your release branch, including nothing but the bug fix), what happens to your development version number after that?
Author
Owner

@ljharb commented on GitHub (Sep 11, 2020):

@vcorr the next one would be v1.2.2-dev or whatever postfix you prefer.

<!-- gh-comment-id:690904772 --> @ljharb commented on GitHub (Sep 11, 2020): @vcorr the next one would be v1.2.2-dev or whatever postfix you prefer.
Author
Owner

@ygoe commented on GitHub (Sep 11, 2020):

@vcorr Version numbers are assigned automatically based on previous version tags up the history. The release branch and the main branch are unrelated and will never be merged, so they don't interact with each other regarding their version numbers. It is the task of the maintainer to assign proper version tags. So if I set the 1.2.1 tag on the release/1.2 branch, that doesn't affect the main branch in any way. It will still see 1.2.0 as its latest version tag and continue to generate 1.2.1-dev numbers. But as is the meaning of a pre-release, none of them can be assumed compatible (or ordered across certain boundaries) with any other pre-release. For example, our versions are built like this:

1.2.1-44-feature-name.5+1a2b3c

  • 1.2.1 is the next patch version, because we need something that's minimally greater than the latest release 1.2.0.
  • - indicates the pre-release
  • 44 is the issue number of the work branch
  • feature-name is the issue title (44-feature-branch is the full branch name)
  • 5 is the number of commits after the latest version tag, 1.2.0. It counts along the path (in Git) so it may become smaller again for new branches.
  • 1a2b3c is the commit hash that uniquely identifies the commit we have built. This will be used to find the code for a pre-release version.

Obviously, when you finish work on issue 44 and then continue with issue 38, the version number will appear smaller. But there's no way to change that. This is simply the fate of generated pre-release version numbers in a multi-branch environment. Hence, they must all be assumed incompatible with each other. Only comparisons to release versions or within the same branch are allowed.

<!-- gh-comment-id:690935795 --> @ygoe commented on GitHub (Sep 11, 2020): @vcorr Version numbers are assigned automatically based on previous version tags up the history. The release branch and the main branch are unrelated and will never be merged, so they don't interact with each other regarding their version numbers. It is the task of the maintainer to assign proper version tags. So if I set the 1.2.1 tag on the release/1.2 branch, that doesn't affect the main branch in any way. It will still see 1.2.0 as its latest version tag and continue to generate 1.2.1-dev numbers. But as is the meaning of a pre-release, none of them can be assumed compatible (or ordered across certain boundaries) with any other pre-release. For example, our versions are built like this: 1.2.1-44-feature-name.5+1a2b3c * 1.2.1 is the next patch version, because we need something that's minimally greater than the latest release 1.2.0. * `-` indicates the pre-release * 44 is the issue number of the work branch * feature-name is the issue title (44-feature-branch is the full branch name) * 5 is the number of commits after the latest version tag, 1.2.0. It counts along the path (in Git) so it may become smaller again for new branches. * 1a2b3c is the commit hash that uniquely identifies the commit we have built. This will be used to find the code for a pre-release version. Obviously, when you finish work on issue 44 and then continue with issue 38, the version number will appear smaller. But there's no way to change that. This is simply the fate of generated pre-release version numbers in a multi-branch environment. Hence, they must all be assumed incompatible with each other. Only comparisons to release versions or within the same branch are allowed.
Author
Owner

@ljharb commented on GitHub (Sep 11, 2020):

@ygoe "branches" have nothing to do with semver, nor does your individual repository's workflow. You're making a lot of assumptions about tooling that may not even exist for others, and about what this tooling would do for others. Many workflows don't even have a different "release" and "main" branch - there's just the one main branch, from which all releases are done.

<!-- gh-comment-id:691322036 --> @ljharb commented on GitHub (Sep 11, 2020): @ygoe "branches" have nothing to do with semver, nor does your individual repository's workflow. You're making a lot of assumptions about tooling that may not even exist for others, and about what this tooling would do for others. Many workflows don't even have a different "release" and "main" branch - there's just the one main branch, from which all releases are done.
Author
Owner

@ygoe commented on GitHub (Sep 11, 2020):

@ljharb Then SemVer does not apply to those workflows or leads to undefined behaviour. It's just not specified. So I could only describe my workflow.

<!-- gh-comment-id:691339738 --> @ygoe commented on GitHub (Sep 11, 2020): @ljharb Then SemVer does not apply to those workflows or leads to undefined behaviour. It's just not specified. So I could only describe my workflow.
Author
Owner

@ljharb commented on GitHub (Sep 11, 2020):

Totally fine to describe your own workflow! Semver however applies perfectly fine to those workflows, since in many ecosystems, git doesn't contain released artifacts, and an artifact is "published" by pushing to another, separate registry.

<!-- gh-comment-id:691351270 --> @ljharb commented on GitHub (Sep 11, 2020): Totally fine to describe your own workflow! Semver however applies perfectly fine to those workflows, since in many ecosystems, git doesn't contain released artifacts, and an artifact is "published" by pushing to another, separate registry.
Author
Owner

@vcorr commented on GitHub (Sep 12, 2020):

Since you mentioned release artifacts... Assuming you only have one artifact repository for both prod and dev, how do you deal with the situation, where you have 1.2.0 in production, you are working with 1.2.1-dev towards next release and now you need to make a bug fix to prod with 1.2.1?

Artefacts repository:

  • 1.2.0 (current prod)
  • 1.2.1-dev.1 (new features)
  • 1.2.1-dev.2 (new features)
  • 1.2.1 (bugfix, from release branch etc. , with only the bug fix)

1.2.1-dev.3 would be considered earlier than 1.2.1.

For instance Helm charts need to be Semver versioned and if you want to keep your development version open with something like ~1.2 it would now pick up the latest of that, 1.2.1 and not 1.2.1-dev.3

<!-- gh-comment-id:691435288 --> @vcorr commented on GitHub (Sep 12, 2020): Since you mentioned release artifacts... Assuming you only have one artifact repository for both prod and dev, how do you deal with the situation, where you have 1.2.0 in production, you are working with 1.2.1-dev towards next release and now you need to make a bug fix to prod with 1.2.1? Artefacts repository: * 1.2.0 (current prod) * 1.2.1-dev.1 (new features) * 1.2.1-dev.2 (new features) * 1.2.1 (bugfix, from release branch etc. , with only the bug fix) 1.2.1-dev.3 would be considered earlier than 1.2.1. For instance Helm charts need to be Semver versioned and if you want to keep your development version open with something like ~1.2 it would now pick up the latest of that, 1.2.1 and not 1.2.1-dev.3
Author
Owner

@ljharb commented on GitHub (Sep 12, 2020):

@vcorr that's why i'd release it as v1.2.2-dev.0.

All prereleases are just throwaways. Once v1.2.2 is out, all prereleases for v1.2.2 are obsolete.

In npm, ~ and ^ won't pick up prereleases by default - prereleases are only picked up explicitly.

<!-- gh-comment-id:691436613 --> @ljharb commented on GitHub (Sep 12, 2020): @vcorr that's why i'd release it as `v1.2.2-dev.0`. All prereleases are just throwaways. Once v1.2.2 is out, all prereleases for v1.2.2 are obsolete. In npm, `~` and `^` won't pick up prereleases by default - prereleases are only picked up explicitly.
Author
Owner

@ygoe commented on GitHub (Sep 12, 2020):

What is an artefact repository? Is that a store for released (binary/compiled) bits? Why should this store contain prereleases? After all, if it's released, it's not a prerelease anymore – it's a release. And that must be assigned a public and comparable version. But if you add a hotfix to 1.2.0 and call it 1.2.1, who says that the main development does contain that fix after all? It could be a fix that's only relevant to the state 1.2.0 was in and may be obsolete by other changes for 1.3.0. So the presence of the fix in the 1.2 branch does not necessarily imply that it's "more" than the current main development. And other prereleases may not even contain that fix because they're built from other unfinished work branches that will never see that fix.

It's complicated and unless you want to assign versions to each commit/prerelease manually and carefully, you have to use an automatic scheme that cannot consider all parallel developments but only the definitive history of the part to look at. YMMV.

<!-- gh-comment-id:691453965 --> @ygoe commented on GitHub (Sep 12, 2020): What is an artefact repository? Is that a store for released (binary/compiled) bits? Why should this store contain prereleases? After all, if it's released, it's not a prerelease anymore – it's a release. And that must be assigned a public and comparable version. But if you add a hotfix to 1.2.0 and call it 1.2.1, who says that the main development does contain that fix after all? It could be a fix that's only relevant to the state 1.2.0 was in and may be obsolete by other changes for 1.3.0. So the presence of the fix in the 1.2 branch does not necessarily imply that it's "more" than the current main development. And other prereleases may not even contain that fix because they're built from other unfinished work branches that will never see that fix. It's complicated and unless you want to assign versions to each commit/prerelease *manually* and *carefully*, you have to use an automatic scheme that cannot consider all parallel developments but only the definitive history of the part to look at. YMMV.
Author
Owner

@ljharb commented on GitHub (Sep 13, 2020):

For node packages, it’s an npm registry. For ruby gems, it’s rubygems.com or similar. Most languages have some sort of location for published artifacts that’s different from the repository, whether it’s a prerelease or not. Git is for development, not distribution.

<!-- gh-comment-id:691608804 --> @ljharb commented on GitHub (Sep 13, 2020): For node packages, it’s an npm registry. For ruby gems, it’s rubygems.com or similar. Most languages have some sort of location for published artifacts that’s different from the repository, whether it’s a prerelease or not. Git is for development, not distribution.
Author
Owner

@ygoe commented on GitHub (Sep 13, 2020):

As I understand it, everything that's published to these locations has a proper assigned version number. This would be tagged as such in Git so that you know what code belongs to that released thing, because somebody external might refer to such a version. Whether it's called 1.0.0 or 1.2.4 or 1.3.6-rc.2. If it contains a dash you must make sure that those versions have a defined order. You probably wouldn't feed daily unreviewed builds automatically into these places, with branch names and commit counts.

<!-- gh-comment-id:691631283 --> @ygoe commented on GitHub (Sep 13, 2020): As I understand it, everything that's published to these locations has a proper assigned version number. This would be tagged as such in Git so that you know what code belongs to that released thing, because somebody external might refer to such a version. Whether it's called 1.0.0 or 1.2.4 or 1.3.6-rc.2. If it contains a dash you must make sure that those versions have a defined order. You probably wouldn't feed daily unreviewed builds automatically into these places, with branch names and commit counts.
Author
Owner

@vcorr commented on GitHub (Sep 13, 2020):

You probably wouldn't feed daily unreviewed builds automatically into these places, with branch names and commit counts.

Not to public repositories, no, but depending on your setup it may be required to push them somewhere in order to automate updating development environments. In the production bug fix scenario above, there are two possibilities, either as @ljharb pointed out, bump the patch version in development, or host a completely separate artifact repository for development. I find the first option quite sufficient.

<!-- gh-comment-id:691635343 --> @vcorr commented on GitHub (Sep 13, 2020): > You probably wouldn't feed daily unreviewed builds automatically into these places, with branch names and commit counts. Not to public repositories, no, but depending on your setup it may be required to push them somewhere in order to automate updating development environments. In the production bug fix scenario above, there are two possibilities, either as @ljharb pointed out, bump the patch version in development, or host a completely separate artifact repository for development. I find the first option quite sufficient.
Author
Owner

@jayschwa commented on GitHub (Oct 2, 2020):

The next nightly should just be a prerelease. If you don't know what version it'll be, make it a patch prerelease. once you know it's a minor or a major, make it a prerelease of that.

This is worth putting in the FAQ if none of the fancier "ordered, unstable post-release" ideas are likely to be accepted.

<!-- gh-comment-id:702535330 --> @jayschwa commented on GitHub (Oct 2, 2020): > The next nightly should just be a prerelease. If you don't know what version it'll be, make it a patch prerelease. once you know it's a minor or a major, make it a prerelease of that. This is worth putting in the FAQ if none of the fancier "ordered, unstable post-release" ideas are likely to be accepted.
Author
Owner

@mentalisttraceur commented on GitHub (Oct 2, 2020):

@vcorr If you're doing that, the important question is: do you want automatic updates or admins or users to install those nightly builds or not?

Regardless of whether or not you have automatic updates, even if you intend to never have them, even if you teach everyone with download or install permissions to never grab those packages - if you upload unvetted builds to the same repository as your vetted builds with a higher version number, you are saying something.

If you are using a package system which honors SemVer notions of pre-release versions, then that's fine, because in the semantics of that package system, you can say "this is a version you should ignore, because there are no compatibility guarantees" with either pre-release versions or 0.* versions.

But in package systems that don't do that, you might be saying "this is the newest version, prefer this one unless you know you want an older one".

If you are using a package system you have to speak its language.

And that means if you are using it to shove builds into the same update channel as your vetter builds, you have to figure out a way to say "this is not an upgrade" in that package system's language. Otherwise you are lying (in the language of your packaging system). Which might be fine, lying isn't always wrong. You or your team are allowed to decide that a given lie is fine in your case. Just understand it has the same risks and tradeoffs as any other deliberate miscommunication.

Drropping the unvetted builds down to 0.* versions is one way to do that which will say the right thing in many package systems, while saying the right thing in SemVer. (Or if you have official 0.* releases, you can drop unvetted builds all the way down to 0.0.0-* as needed.)

But no amount of explicit "nightly" support in SemVer will work around the fact that you'll still have to express "don't update to this!" in the language of your package system, and SemVer can't cover all package systems. For those other package systems, making all your nightlies 0.0.0-* and putting the other information like git hash or tentative version or last official version after that in the version number is a pretty universal fallback.

<!-- gh-comment-id:702971596 --> @mentalisttraceur commented on GitHub (Oct 2, 2020): @vcorr If you're doing that, the important question is: do you want automatic updates or admins or users to install those nightly builds or not? Regardless of whether or not you *have* automatic updates, even if you intend to never have them, even if you teach everyone with download or install permissions to never grab those packages - *if you upload unvetted builds to the same repository as your vetted builds with a higher version number, you are **saying something***. If you are using a package system which honors SemVer notions of pre-release versions, then that's fine, because in the semantics of that package system, you can say "this is a version you should ignore, because there are no compatibility guarantees" with either pre-release versions or `0.*` versions. But in package systems that don't do that, you might be saying "this is the newest version, prefer this one unless you know you want an older one". ***If you are using a package system you have to speak its language***. And that means if you are using it to shove builds into the same update channel as your vetter builds, you have to figure out a way to say "this is not an upgrade" in that package system's language. Otherwise you are lying (in the language of your packaging system). Which might be fine, lying isn't always wrong. You or your team are allowed to decide that a given lie is fine in your case. Just understand it has the same risks and tradeoffs as any other *deliberate miscommunication*. Drropping the unvetted builds down to `0.*` versions is one way to do that which will say the right thing in many package systems, while saying the right thing in SemVer. (Or if you have official `0.*` releases, you can drop unvetted builds all the way down to `0.0.0-*` as needed.) But no amount of explicit "nightly" support in SemVer will work around the fact that you'll still have to express "don't update to this!" in the language of your package system, and SemVer can't cover all package systems. For those other package systems, making all your nightlies `0.0.0-*` and putting the other information like git hash or tentative version or last official version after that in the version number is a pretty *universal* fallback.
Author
Owner

@mentalisttraceur commented on GitHub (Oct 2, 2020):

The next nightly should just be a prerelease. If you don't know what version it'll be, make it a patch prerelease. once you know it's a minor or a major, make it a prerelease of that.

This is worth putting in the FAQ if none of the fancier "ordered, unstable post-release" ideas are likely to be accepted.

I think the FAQ should also explicitly mention:

  1. That maybe your nightlies should not be SemVer'ed at all, even if your official releases are.

  2. That maybe package systems which are intended to support nightlies should not force SemVer.

  3. The 0.0.0-* nightly versioning alternative to prerelease versioning, which is the more universal fallback that works in almost all cases.

Because nightly versioning is often a problem of saying the right thing in the language of your specific package system, not a problem of saying the right thing in the language of SemVer.

There is some overlap in saying what nightlies want to say in both languages (SemVer pre-releases if the package system knows not to treat them as upgrades) but for the most part they are just separate.

<!-- gh-comment-id:702979091 --> @mentalisttraceur commented on GitHub (Oct 2, 2020): > > The next nightly should just be a prerelease. If you don't know what version it'll be, make it a patch prerelease. once you know it's a minor or a major, make it a prerelease of that. > > This is worth putting in the FAQ if none of the fancier "ordered, unstable post-release" ideas are likely to be accepted. I think the FAQ should *also* explicitly mention: 1. That maybe your nightlies should not be SemVer'ed at all, even if your official releases are. 2. That maybe package systems which are intended to support nightlies should not force SemVer. 3. The `0.0.0-*` nightly versioning alternative to prerelease versioning, which is the more universal fallback that works in almost all cases. Because nightly versioning is often a problem of saying the right thing *in the language of your specific package system*, not a problem of saying the right thing in the language of SemVer. There is some overlap in saying what nightlies want to say in both languages (SemVer pre-releases if the package system knows not to treat them as upgrades) but for the most part they are just separate.
Author
Owner

@alexandrtovmach commented on GitHub (May 14, 2021):

SemVer spec is something stable and strict, and if you want to change it, please create fork or start another project

closing in favor of https://github.com/semver/semver/issues/703#issuecomment-841420754

<!-- gh-comment-id:841432567 --> @alexandrtovmach commented on GitHub (May 14, 2021): >SemVer spec is something stable and strict, and if you want to change it, please create fork or start another project closing in favor of https://github.com/semver/semver/issues/703#issuecomment-841420754
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#5252