New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nightly builds not supported #200

Open
mearns opened this Issue May 20, 2014 · 72 comments

Comments

Projects
None yet
@mearns
Copy link

mearns commented May 20, 2014

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.

@mearns mearns changed the title Post-release suffix requirements on version Nightly builds not supported May 20, 2014

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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.

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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."

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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.

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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.

@FichteFoll

This comment has been minimized.

Copy link

FichteFoll commented May 20, 2014

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

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented May 21, 2014

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

@FichteFoll

This comment has been minimized.

Copy link

FichteFoll commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@damianpowell

This comment has been minimized.

Copy link

damianpowell commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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).

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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.

@EddieGarmon

This comment has been minimized.

Copy link
Contributor

EddieGarmon commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@EddieGarmon

This comment has been minimized.

Copy link
Contributor

EddieGarmon commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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".

@EddieGarmon

This comment has been minimized.

Copy link
Contributor

EddieGarmon commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@zafarkhaja

This comment has been minimized.

Copy link

zafarkhaja commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@FichteFoll

This comment has been minimized.

Copy link

FichteFoll commented 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.)

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@FichteFoll

This comment has been minimized.

Copy link

FichteFoll commented 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).

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@FichteFoll

This comment has been minimized.

Copy link

FichteFoll commented 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.

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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).

@crazedsanity

This comment has been minimized.

Copy link

crazedsanity commented 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?

@Abdillah

This comment has been minimized.

Copy link

Abdillah commented 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 😄..

@olivier-spinelli

This comment has been minimized.

Copy link

olivier-spinelli commented 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.

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@FichteFoll

This comment has been minimized.

Copy link

FichteFoll commented 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.

@judgeaxl

This comment has been minimized.

Copy link

judgeaxl commented 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.

@ygoe

This comment has been minimized.

Copy link

ygoe commented 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?

@mearns

This comment has been minimized.

Copy link
Author

mearns commented 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.

@jwdonahue

This comment has been minimized.

Copy link
Contributor

jwdonahue commented 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.

@olivier-spinelli

This comment has been minimized.

Copy link

olivier-spinelli commented 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.

@ygoe

This comment has been minimized.

Copy link

ygoe commented Dec 8, 2017

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

dhebbeker added a commit to dhebbeker/memorex-android that referenced this issue Mar 28, 2018

Added rule on how to name development versions.
This rule has been written after studying this discussion [1] about post-release version naming.
Documented example for version tag name.

[1]: semver/semver#200
@mentalisttraceur

This comment has been minimized.

Copy link

mentalisttraceur commented 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.

@jwdonahue

This comment has been minimized.

Copy link
Contributor

jwdonahue commented 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.

@olivier-spinelli

This comment has been minimized.

Copy link

olivier-spinelli commented 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).

@jwdonahue

This comment has been minimized.

Copy link
Contributor

jwdonahue commented 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.

@judgeaxl

This comment has been minimized.

Copy link

judgeaxl commented 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.

@olivier-spinelli

This comment has been minimized.

Copy link

olivier-spinelli commented 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.

@olivier-spinelli

This comment has been minimized.

Copy link

olivier-spinelli commented 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.)

@jwdonahue

This comment has been minimized.

Copy link
Contributor

jwdonahue commented 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.

@jwdonahue

This comment has been minimized.

Copy link
Contributor

jwdonahue commented 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment