Skip to content
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

Closed
mearns opened this issue May 20, 2014 · 96 comments
Closed

Nightly builds not supported #200

mearns opened this issue May 20, 2014 · 96 comments

Comments

@mearns
Copy link

@mearns 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
Copy link

@crazedsanity 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
Copy link

@crazedsanity 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
Copy link
Author

@mearns 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
Copy link

@crazedsanity 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
Copy link

@crazedsanity 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
Copy link

@FichteFoll 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
Copy link

@crazedsanity crazedsanity commented May 21, 2014

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

@FichteFoll
Copy link

@FichteFoll 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
Copy link
Author

@mearns 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
Copy link
Author

@mearns 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
Copy link

@damianpowell 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
Copy link
Author

@mearns 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
Copy link

@crazedsanity 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
Copy link
Contributor

@EddieGarmon 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
Copy link
Author

@mearns 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
Copy link
Contributor

@EddieGarmon 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
Copy link
Author

@mearns 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
Copy link
Contributor

@EddieGarmon 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
Copy link
Author

@mearns 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
Copy link

@zafarkhaja 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
Copy link
Author

@mearns 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
Copy link

@FichteFoll 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
Copy link
Author

@mearns 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
Copy link

@FichteFoll 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
Copy link
Author

@mearns 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
Copy link

@FichteFoll 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
Copy link

@crazedsanity 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
Copy link
Author

@mearns 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
Copy link

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

@alexandrtovmach
Copy link
Member

@alexandrtovmach alexandrtovmach commented Jun 10, 2020

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

@ljharb
Copy link
Contributor

@ljharb ljharb commented 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.

@olivier-spinelli
Copy link

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

@mentalisttraceur
Copy link

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

@ygoe
Copy link

@ygoe ygoe commented 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.

@FichteFoll
Copy link

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

@steveklabnik
Copy link
Member

@steveklabnik steveklabnik commented Jun 14, 2020

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

@vcorr
Copy link

@vcorr vcorr commented 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?

@ljharb
Copy link
Contributor

@ljharb ljharb commented Sep 11, 2020

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

@ygoe
Copy link

@ygoe ygoe commented 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.

@ljharb
Copy link
Contributor

@ljharb ljharb commented 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.

@ygoe
Copy link

@ygoe ygoe commented 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.

@ljharb
Copy link
Contributor

@ljharb ljharb commented 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.

@vcorr
Copy link

@vcorr vcorr commented 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

@ljharb
Copy link
Contributor

@ljharb ljharb commented 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.

@ygoe
Copy link

@ygoe ygoe commented 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.

@ljharb
Copy link
Contributor

@ljharb ljharb commented 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.

@ygoe
Copy link

@ygoe ygoe commented 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.

@vcorr
Copy link

@vcorr vcorr commented 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.

@jayschwa
Copy link

@jayschwa jayschwa commented 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.

@mentalisttraceur
Copy link

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

@mentalisttraceur
Copy link

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

@alexandrtovmach
Copy link
Member

@alexandrtovmach alexandrtovmach commented 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 #703 (comment)

qub1750ul pushed a commit to qub1750ul/versioning that referenced this issue Jul 10, 2021
Clear ambiguity in French translation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet