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

[RFC] New post release syntax / change for build metadata syntax #519

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

sylr
Copy link

@sylr sylr commented May 28, 2019

A post release syntax is useful for hot fix versions and for people maintaining patch sets on top of official versions that did not make it to the official release (whether is hasn't made the cut or because it has been refused).

According to me the most logical syntax for post-release is to use the + sign. As it is already used for build metadata in v2.0.0 I'm suggesting to change build metadata separtor to the ~ sign.

Example: 1.15.3+patchset.1~go1.11, 1.15.3+patchset.1~go1.12

Real life example: linux-4.4.190+rt.187 -> linux kernel 4.4.190 with RT patch version 187.

The downside of this is that would be a breaking change.

EDIT: Change example to use patchset instead of hotfix which is confusing as hotfix automatically yields patch version increment (one quickly forgets that this RFC aims to enabled non official releases from people who needs to manage their own patch sets).

Signed-off-by: Sylvain Rabot <s.rabot@lectra.com>
@FichteFoll
Copy link

FichteFoll commented May 29, 2019

The current wording does not prevent a release from having both a pre-release and a post-release segment, despite this case not being included in the BNF. However, considering how a pre-release is also a release, it should be allowed to have post-releases of pre-releases (for automated/nightly builds).
Furthermore, you should mention the post-release segment in the precedence paragraph (and not just include an example) and you might want to add an FAQ entry explaining what this can be used for.

Other than that, I like this proposal, as I have voiced years ago in #200 (comment). The only problem is the huge breaking change regarding the + symbol, but fortunately it seems quite rarely used.

@runeimp
Copy link

runeimp commented May 29, 2019

In FreeBSD (and a few other places) you'll often see code ported to that OS often coming in with say version 1.2.3 to the package system and then being patched shortly thereafter as 1.2.3_1 and then (on rare occasions) repatched with an updated patch to 1.2.3_2, etc. If post release numbers are added to the spec then I'd be happier if it followed "prior art", as it were. This would also be less likely to cause confusion "Why is my semver parser tool caring about the build version now?" or "Why isn't my semver parser tool caring about the new post-release version?", etc.

@runeimp
Copy link

runeimp commented May 29, 2019

And personally I'd rather have any code that parses SemVer gack on the addition of a new yet unsupported feature than assume everything is fine because the syntax has new meaning. Following concept of Path of least surprise.

That said I also personally greatly prefer the syntax change. - and + designating pre-release and post-release is MUCH more natural than say - and ~ or anything else. And it bugs me that I new if SemVer ever did support post-release versioning that + was already used for build metadata. Oh well.

@FichteFoll
Copy link

FichteFoll commented Jun 3, 2019

If post release numbers are added to the spec then I'd be happier if it followed "prior art", as it were.

There is a lot of "prior art" available here, however. Arch appends a "post-release" number called pkgrel with a hyphen, for example. So does git describe. But a hyphen is infeasible as it is incompatible with pre-releases and that shouldn't change.

The advantage of using _ over + would be that it's less confusing with the current usage of + for build metadata (but I believe that to be a poor choice to begin with and this would be a good chance to change it).

@jwdonahue
Copy link
Contributor

The spec already covers post releases. They are every minor and patch release (M.y.z) that come after the major release (M.0.0). I argue that anyone who feels the need to add additional "post-release" digits to any version scheme, has serious DevOps issues. I am fine with some version schemes providing a release valve for such poorly planned/executed development environments, but I see no need for SemVer to cover them.

@sylr
Copy link
Author

sylr commented Aug 17, 2019

@jwdonahue The serious DevOps issue you are referring to is called “contributing to open source”. Something your GitHub account shows you know little about.

@jwdonahue
Copy link
Contributor

@sylr, it's true, I have been busy getting paid to help create hardware and software used around the world by about a billion people, but I have also been contributing here of late, as well. But ya, you can find way more examples of poorly run projects in the OSS community than there are good ones, so I guess we can agree on that as well.

Just an FYI, GitHub stats don't really say much about anybody's life-long contributions to anything but GutHub, which is really not very important in the grand scheme of things. I've been designing/building hardware for 40 years and made a good living developing software for 30.

I am just of the opinion that SemVer doesn't need any more digits added to it. It doesn't need "post releases" either. The preponderance of requests to add one or more digits, for various purposes, to SemVer is evidence we need a more flexible scheme. I don't think any one standard is ever going to be good enough, so why not evolve to something like VesionMeta and VersionSchema? A standard you can wield to define your development and release practices that is both human readable and can be processed by machine intelligence, without lock-in to least common denominator, is ultimately going to supplant all the other versioning standards.

BTW: Nuget and, I am pretty sure, NPM (certainly others), already provide support for four digit version numbers. There's nothing wrong with using alternative schemes. SemVer is just not a suitable venue to codify those other schemes.

@jwdonahue
Copy link
Contributor

@FichteFoll

The only problem is the huge breaking change regarding the + symbol, but fortunately it seems quite rarely used.

I can attest that it is in common enough use, that breaking it, will cause a great deal of economic damage. I know of a build ecosystem with 10K+ users that definitely use it every day (I wrote the tooling for it). I often use it to simply embed the Git hash(s) that the product was built from. It's my opinion that redefining the meaning of the plus, minus or period symbols isn't just a breaking change, it would be incredibly stupid to do so, without also adding some kind of Version Meta to the string, in order to disambiguate their semantics.

SemVer 1 is syntactically a subset of SemVer 2, so while there were some subtle rules changes that were indeed breaking between them, in practice, SemVer 2 code generally works just fine when presented with a SemVer 1 string, and I think it may be the case that SemVer 2 is more widely implemented than v1. Basically, SemVer 2 has become a gold-standard in the community. I would be okay if v2 turns out to be a subset of v3 syntactically, and preferably semantically, but I do view additions to the SemVer spec, as the equivalent of putting lipstick on a pig.

If you must dress her up, I think the plus symbol should always be interpreted as the start of the build meta tag, but I also think it should not be required for it. The plus symbol causes no end of problems with URL's, due its special meaning to web servers. It should be deprecated in favor of some other symbol. Any new tags or version fields should be denoted by symbol(s) not currently in use, and should be selected to avoid issues with URL's.

If you must have a band-aide field, why not lead with it. The semantics are hotfix N for version X.Y.Z yes? Then why not something like @1-X.Y.Z? If you really need to hotfix X.Y.Z, then you've probably already pulled it from your feeds. Many semver parsers expect strings like <IgnoredStuff><SemVer>, so the @1- isn't likely to break the SemVer parser. One drawback is that v2 parsers, won't apply the hot-fix for X.Y.Z if they already have it, but they will apply it otherwise, if it matches their dependency spec, and a human looking at a list of semverized package names, is going to see P@1- and realize they need to take that hot-fix, so they'll modify their manifest to pull something different. Well, at least until they update their tooling to v3, which should nearly always apply hot-fixes to existing versions.

Ultimately, we're really talking about a request for tooling changes with this PR. We get a lot of those here, because folks assume that if they can get the Spec changed, that tool owners will fall in line. I think the evidence suggests otherwise.

@FichteFoll
Copy link

I believe there is a misunderstanding in this discussion. This isn't about masking a hotfix release as something that "hotfixes this particular version" because that doesn't make sense in semver's philosophy in the first place. The proper way to release a hotfix is to increase the patch version number.
The idea behind post-release descriminators is to have a more or less common practice for development build artifacts that are specifically not explicitly releases.

That said, I do agree with @jwdonahue that this is kind of more of a tooling suggestion or an appendix to semver because it doesn't need a concept of post-releases when it mostly adheres to users of a library. The real world begs to differ here and with the wide usage of VCS or CI you might end up with the desire to add a version descriminator to any commit to the master branch just so you have a way to name that artifact (probably incrementally) that does rely purely on hashes. I suggest reading up on #200 if you're looking for real world examples.


As a compromise, metadata does offer itself to be abused in this way such that you just tack an incrementing number to a previously released version number and optionally the commit hash it was produced from, e.g. 1.2.3+r.45.f8622ab, which then gets a specific meaning depending on your tooling. Semver by itself claims that the same versions with different metadata are uncomparable, but your tooling might be able to adapt to this if you really need to compare these hacked post-release versions. (In fact, my own semver implementation does this because this wasn't prohibited in semver 2.0.0-rc.2.)

Alas, I believe that a backwards-incompatible change like the proposed one is indeed an almost impossible uphill battle against the legacy of the + glyph being used for metadata.

The usage of an underscore _ glyph, however, would be backwards-compatible and still require tooling to be changed accordingly, but is much more closer in effort to adding an option for including metadata in precedence. The result would be a version like 1.2.3-beta.1_4+windows.22f263b. I suppose it is debatable whether the underscore stands out enough in a string like this.

@grv87
Copy link

grv87 commented Aug 26, 2019

@FichteFoll, @sylr, please, don't use _ in the standard. There are already cases where + is not supported, and _ is used instead. See #145 (comment)

@jwdonahue
Copy link
Contributor

@grv87,

There's lots of potential ways that a SemVer string could be translated for compatibility purposes that would use any character not defined in the SemVer spec. Future symbol additions to the spec will require a great deal of care, but ultimately, the choices we've made wrt translations may be important in some of the larger developer communities, those choices are not binding on future versions of the spec.

One of the weaknesses of SemVer is that the string itself, cannot be used to unambiguously discriminate from one version of the spec to the next. I will be in here fighting to remedy that issue for the next major version, should that ever arrive.

@dcleao
Copy link

dcleao commented Sep 10, 2019

Support for post-release (similar to maven SNAPSHOT builds) versions is essential to implement a CI system where, after a release (presumably, a public one) it is not yet certain what type of release will follow. Depending on the changes which come to be performed, either a patch, minor or major increment may follow. Assuming either, preventively, may have unwanted consequences. This has been extensively described, and many times, in other related issues of this repository.
It is frequently not feasible or practical to do the type-of-change analysis, and corresponding version bump, on every commit; this is true despite the existence of tooling that tries to automate this task, based on commit messages. Rather, version bumps, of an appropriate type, are made in their own commits, acknowledging the whole set of changes made since the last "public" (non-post) release.

It has many times been called to attention that post-release versions are not the same as the metadata information, and that the latter must not affect the order of precedence...

The discussion and bike-shedding on the actual character that comes to introduce this new section is welcome but, imo, should not defer us from agreeing that this style of versioning is actually needed and that should be part of semantic versioning. Even if this is only used for supporting CIs and internal, not public, releases. Developers spend long periods of time with internal, transient releases... We can assume the character is > for now, and replace it later with an appropriate one.

Even the discussion of whether the current character that introduces the build metadata section, + should be changed so that this new feature can use it, and thus whether a breaking change should be introduced, can be deferred to a later time... after we've settled on the actual semantics and gross syntax of the new post-release section...

Please, guys! This is a feature which is very much needed to support today's versioning styles and CI systems. Not defining this in the semver spec forces everyone to abuse the metadata section and implement custom semver-like parsers and sort rules.

@jwdonahue
Copy link
Contributor

jwdonahue commented Sep 11, 2019

Support for post-release (similar to maven SNAPSHOT builds) versions is essential to implement a CI system where, after a release (presumably, a public one) it is not yet certain what type of release will follow.

That statement is untrue. I have personal experience with a half dozen CI systems that use semver. Since only one example to the contrary is required as proof of a false statement, I give you this:

1.0.0
1.0.1-a.CI
...
1.0.93-a.CI
1.1.0-a.flight1
1.2.1-a.CI
etc.

What is needed to support today's versioning schemes and CI systems, is a new and entirely different standard than semver. Whatever you would change semver to, there's always going to be a huge range of folks who will not adopt it, because it does not meet their needs. So lets define a standardized way to define your scheme and label your version strings appropriately, such that humans and machines can reason over whatever your semantics are.

My personal preference would be something along the lines of:

0001+checkinId.branchName {CIB}
0002+checkinId.branchName {CIB}
...
1019+checkinId.branchName {CIB}
1020+checkinId.master {CIB}
0.1.0+1020 {Flight}
1021+checkinId.branchName {CIB}
...
1.0.0-beta.1+2561 {SemVer}

The bits between and including the braces are the {VersionMeta} strings that, in this case, identify "well known" VersionSchema. It's a project I've been cooking, off and on, for the past couple of years, after spending quite a bit of free time reading every single issue and PR that's been posted here at semver/semver and responding to more than a few of them.

So the way the above history would have played out (ignoring many details) is, a developer sets up a DevOps project with a repo and standard build logic, then starts pushing their changes to a working branch that has CI builds enabled. By 1019+checkinId.branchName {CIB} the dev(s) are ready to push their first feature for "internal" flight testing and issue a PR to master. Once accepted to master the CIB produces 0.1.0+1020 {Flight}, which the sales force, executives, secretaries and selected early adopters can get their hands on and start providing feedback. Many iterations and features later, with many branches feeding into master, we get to 1.0.0-beta.1+2561 {SemVer}, which is the VersionMeta form of a SemVer version string.

Your developer's relationships with internal/external stake-holders will vary from mine, so the above is just one example of the possibly infinite number of schemes that could be defined by VersionMeta, which needs a lot of hard work to get it ready for prime-time. Note that I am not suggesting the promotion of infinite numbers of schemes, only that a good standard, would allow for them, while providing a range of common, well-known, predefined variations for general use.

@dcleao
Copy link

dcleao commented Sep 11, 2019

Dear @jwdonahue,

That statement is untrue. I have personal experience with a half dozen CI systems that use semver. Since only one example to the contrary is required as proof of a false statement, I give you this:

1.0.0
1.0.1-a.CI
...
1.0.93-a.CI
1.1.0-a.flight1
1.2.1-a.CI
etc.

If I understand correctly what you mean, when 1.0.1-a.CI was created, after 1.0.0, how was it decided that the next (proper) release would be 1.0.1?
How is it known, by the time of the first commit, that the changes in that commit, and in all future commits until a point when a proper release is decided to be created, will be "patch" level?

According to the proposed post-release scheme, you would, instead, continue development by creating the release 1.0.0>1 (if we assume > is the post-release section symbol). In this solution, you do not compromise the proper use of the 1.0.1 version for an actual patch, if one comes to be necessary. Each new further-development commit would trigger CI into creating subsequent post-release versions 1.0.0>2, 1.0.0>3, 1.0.0>4, etc.

If the solution that you propose compromises the patch version for WIP development, then it isn't a solution to the stated problem and so it does not prove that my statement is untrue (using your chosen terms).

In the other part of your message, you introduce yours VersionSchema and VersionMeta. I don't want to even question the usefulness of these standards and I sincerely hope that one day they will effectively solve the problem of versioning, generally and elegantly, for all package managers and versioning schemes.

I did not understand a good part of your introduction. And I tried, because it could contain some novel idea on how to solve the issue, in semver, or, in any case, it could allow me understand your point of view.

However, this is the repository which governs and maintains semver. If you're not interested in devoting your time to developing semver further, I think that you are in your full right.

I will then only hope that others are still interested in developing semver further, despite of its limitations.

@ljharb
Copy link
Contributor

ljharb commented Sep 11, 2019

Can’t you assume the next one is a patch, until it’s not? Meaning, use 1.0.1 with a prerelease tag. Just because you have a 1.0.1-build.1 doesn’t mean you ever have to have a 1.0.1 - the next release could just as well be 1.1.0 or 2.0.0.

@jwdonahue
Copy link
Contributor

@dcleao

If I understand correctly what you mean, when 1.0.1-a.CI was created, after 1.0.0, how was it decided that the next (proper) release would be 1.0.1?
How is it known, by the time of the first commit, that the changes in that commit, and in all future commits until a point when a proper release is decided to be created, will be "patch" level?

It wasn't "decided". The CI build system simply finds the latest release tag, 1.0.0 in the example, and then bumps the patch number and applies the -a.CI tag to it. That last step says "I am a simple automation and know nothing of the quality of what I just built". As the spec very clearly states, a prerelease tag indicates that any change may be a breaking change. That is just one simple example of a "post release" version string using SemVer.

You can also add the smarts to the CI system, to process semantic commit messages to do more than just use patch as a build number. Either way, any automated system should use the prerelease tag to indicate that anything is actually possible, because short of some really good unit and integration testing, it's often quite hard to get that right. So you leave it up to the wet-ware to eventually cut a proper release.

Your statement was untrue. No special "post-release" semantics are required for CI builds. You must have the prerelease semantics to get the process started, so you have prerelease sequence followed by a release, then rinse and repeat. You can't get the process started with just a postrelease scheme. Why complicate the scheme with both, when the one prerelease tag is sufficient?

Here's the scenario I think you are really hung up about:

1.0.0
1.0.1-a.vNext
1.0.2-a.vNext
1.0.?-Bugfix.1.0.0
1.0.?-a.vNext

Yes? Package or interface names can help:

P.1.0.0
P2.1.0.1-a.vNext
P2.1.0.2-a.vNext
P.1.0.1 // Bug fix!
P2.1.0.3-a.vNext

There are other ways to deal with it.

1.0.0
1.0.1-a.vNext.1
1.2.0-a.vNext.2
1.0.2 // Just the bug fix for 1.0.0 minus the vNext work.

But you have to ask yourself, why would you fix a bug in 1.0.0 and not also fix it in the vNext line of work?

The point here is that postrelease is not needed, prerelease is required and sufficient. Despite the perennial nature of this topic, it has never gotten any traction precisely for that reason.

I sometimes think that real driver for those who strongly feel the need to add postrelease or otherwise extend the spec, is they assume that doing so will just automatically convince all of the tooling owners to adopt the new scheme, which just isn't the case. In fact, the reason the SemVer spec is so stable, is it's pretty much been governed with the needs of those tooling owners in mind.

There's plenty of tool chains out there that roll their own. You are welcome to do so as well. If you do, perhaps you will be kind enough to post and maintain a spec for your peculiar way of doing things?

@dcleao
Copy link

dcleao commented Sep 11, 2019

@jwdonahue:

Your statement was untrue. No special "post-release" semantics are required for CI builds. You must have the prerelease semantics to get the process started, so you have prerelease sequence followed by a release, then rinse and repeat.

You just keep twisting logic and the semantics to your needs... I don't think that you need to "have the pre-release semantics to get the process started". In your versioning scheme, you create a pre-release of a completely hypothetical and artificial release version — the next patch one —, which may never come exist, just to be able to anchor a "sub-version" number with a may-break-anytime semantics (the pre-release version section) to support future development.

With this, you qualify (may transmit the impression of) your future development as something approaching towards 1.0.1 (a patch release), which, by definition of future development, is almost always not the case...

In the process, you get to occupy the pre-release space of the 1.0.1 version with commits which aren't intended to be patches. When and if you actually need and intend to patch 1.0.0, separately from your future development branch, you will, with all propriety, develop for 1.0.1-beta.1, ... versions. Unfortunately, these proper pre-release versions will be all messed up with the previously created pre-release versions...

Many times, you need to patch the last release separately from your current future development — this is because you might have changed the code quite a bit since that release and the fix may need to be made twice...

You can't get the process started with just a postrelease scheme.

Why not?

Why complicate the scheme with both, when the one prerelease tag is sufficient?

Simply, because you will be using pre-releases in unintended, dubious ways.
Pre-release and post-release apply to different operations. The semantics of one does not fit the other.

I sometimes think that real driver for those who strongly feel the need to add postrelease or otherwise extend the spec, is they assume that doing so will just automatically convince all of the tooling owners to adopt the new scheme, which just isn't the case. In fact, the reason the SemVer spec is so stable, is it's pretty much been governed with the needs of those tooling owners in mind.

That's not a driver for me, no. But logic is.

I apologize for my opinion, but by reading issues of the SemVer github repository, over time, I get the impression that its stability is possibly due to the conservationism of its maintainers.

Also, respectfully, I wonder if you opt to only look at the needs of the tool owners that agree with you. I'm almost sure that I've read tool owners and big projects' maintainers, in past issues of this repository, asking for and defending this versioning scheme.

There's plenty of tool chains out there that roll their own. You are welcome to do so as well. If you do, perhaps you will be kind enough to post and maintain a spec for your peculiar way of doing things?

Peculiar way of doing things? You do have a nerve...

@jwdonahue
Copy link
Contributor

Pretty sure that support for post release versions is one of the most perennial requests that we've seen. The proposals take a range of syntactic and semantic forms. I think they are all driven by the messy nature of real-world release cadences and a general lack of study and contemplation on the topic. The subject of version labels is not as simple as one might think it is.

The general view seems to be that there should be one standard that meets all or at least many needs. Since SemVer may be the most widely adopted written standard on the subject of versioning available, the tendency is to push its maintainers to satisfy more of the perceived needs, rather than post a new standard. Folks seem to think that semver/semver is a high traffic zone where their desires can be expressed and received, that will yield results with the least effort. The fact is, the sites that manage to the tools, see a lot more traffic. The folks who maintain those tools are tuned-in to what their customers want and the same people who would implement any changes to the spec.

SemVer is currently managed by a handful of stakeholders in various packaging tools that support SemVer. Many of them recommend its use, some require it. Most of them probably adopted SemVer because their customers asked for it. There's a lot of infrastructure and best practice built up around SemVer 2.0.0, and there's not much to be done with it, that wouldn't be a breaking change for most or all of the stakeholders. Even if you get some or all of the stake-holders to agree to support your post release scheme, they can do so by changing their tooling, without that head-ache of pushing any changes into the SemVer spec. In fact, many of those tools already support version quads, which were pretty much invented to handle the hot-fix scenario, and they did so, in some cases, long before SemVer 1.

One flaw that I see in the spec, is the fact that it doesn't define any way to designate the version of SemVer in use. This means that there's no way, presently, for tooling to determine strictly from the version string, which standard applies. For this reason, you can't just simply append new features, like post-release, without rethinking the entire standard and solving the disambiguation problem. It also implies that the next major release of SemVer, will be the hardest ever, to gain consensus among the stake-holders. If they do that correctly, future upgrades will be handled more gracefully.

@wizzwizz4
Copy link

Why don't you just use the date it's released, or the SVC hash? Since pre-releases aren't stable and don't guarantee an API, they can't really be used with SemVer anyway, so I'm not certain it makes sense to extend SemVer.

@remram44
Copy link

remram44 commented Oct 31, 2019

Something that I don't see mentioned (apologies if I missed it) is the need to support the case where different people use the same version namespace. For example, I might be maintaining a Debian or Conda package, or a Docker image from some Python or NPM package. It is very much needed that my own artifacts follow the versioning of the upstream package it contains/wraps, however my packaging might need versioning on its own.

This is the main use case of the current post-release schemes I believe. More than a few of them use a dash for that (Debian might have 2.1.3-6 or 2.1.3-0ubuntu1 (uses ~ for prereleases; policy), PyPI allows 2.1.3-6 and 2.1.3-post2 (PEP 440). All of those sort after 2.1.3). Bumping the patch version is possible for the upstream package, however I can't make my Conda package 2.1.4, it will conflict with the next upstream patch release. Releasing 2.1.4-0 is possible but very awkward when the upstream version it contains is still 2.1.3.

Every other issue can be worked around I believe, and I agree with the arguments presented here for just bumping the patch number.

I think it is unfortunate that -0 was normalized in semver as meaning a pre-release and no way was included for post-releases. It pushed competing standards in Linux distros and PyPI which I see as a failure of this spec. At least providing a way to do this in semver (though it is unlikely that those existing package managers will be able to migrate) for example through a new character would go a long way towards strict adoption of semver by new systems.

@jwdonahue
Copy link
Contributor

Getting adoption of any standard is equivalent to herding cats.

@remram44
Copy link

remram44 commented Nov 4, 2019

I agree 😅 however that's different from intentionally ignoring uses cases.

Even if, say, ~ was introduced to mark post-releases, we would have semver exactly backwards to what everybody else is doing (~ for pre and - for post). But at least we'd have the complete set of features!

@jwdonahue
Copy link
Contributor

jwdonahue commented Nov 4, 2019

Even if, say, ~ was introduced to mark post-releases, we would have semver exactly backwards to what everybody else is doing (~ for pre and - for post). But at least we'd have the complete set of features!

Everybody? If I had some time to spare, I'd go dig up a handful that don't do that. Perhaps the most common one I've seen in the past is _version_tag_<ws>_qualtiy_tag_.

Your point is taken however. There do seem to be a large number of use cases out there that do it differently. That's not a strong argument however if the use cases that the SemVer maintainers care about, would be completely broken by the change.

How would you distinguish between SemVer v2 and vN? If you have a strong argument to alter both syntax and semantics, you must also solve this problem or it's pretty much a non-starter. Instead, you go put forth the effort to write up the standard you want, give it a non-conflicting name and promote it.

@remram44
Copy link

remram44 commented Nov 5, 2019

Look, I'm not trying to pick a fight. Semver has the merit of existing and that's huge. It's a great solution for those that can use it.

I just think that if there was a way for people who can't use it to have a scheme that looks a little bit compatible to semver, we would all be in a better place. PEP 440 is almost that: semver but with specific words allowed after the dash, with specific semantics; some of it compatible (alpha, beta, rc are pre-releases) and some of it unfortunately not (post, r).

It seems to me that there are ways forward, such as deprecating the use of any word (or most words) after the dash (I think it's safe to assume that if 1.2.3-post.2 occurs today in the wild, it is not meant as a pre-release). If this group has no interest in that, it's fine, I understand, and won't think less of you 😉

Or we could use the +..., which is mostly compatible as well (systems today consider it to mean no change in version and can pick any at random, specifying which one they pick at random isn't a breaking change to the spec. Though it can lead to surprising behavior from incompatible package managers).

@sylr
Copy link
Author

sylr commented Nov 6, 2019

I've updated the example, I changed hotfix by patchset to make it less confusing.

Also added a real life example, the RT patch set for the linux kernel.

@sylr sylr marked this pull request as ready for review November 6, 2019 12:22
@jwdonahue
Copy link
Contributor

Is anyone implementing this in any of the packaging tools? Particularly those that are owned by the maintainers?

@runeimp
Copy link

runeimp commented Jan 16, 2020

I have always felt the need for post release syntax. But I agree with @jwdonahue, et. al. that it is rarely truly needed. The one major exception is patching software for any given OS. My primary example is FreeBSD. Though I'm sure this exists for many other systems (operating systems or otherwise) as well. When someone release a new version of their software through the FreeBSD pkg system it's always something like app-1.2.3 or app-1.2.3.4. But invariably a few days later a patched-for-FreeBSD version is released as app-1.2.3_1 or app-1.2.3.4_1 and occasionally a few days or weeks later another patched-for-FreeBSD version is released as app-1.2.3_2 or app-1.2.3.4_2. Both of those patches are specific to making the software in question work properly or better on the specific OS. And, to my knowledge, don't involve the original author of the software at all. These are not original author planned fixes or updates or preparing for the next release. It's just what is needed to make the software in question work properly or optimally on the OS in question. A true post release situation.

@endorama
Copy link

endorama commented Feb 21, 2020

Hello, I'd like to spend a couple words on this, as I faced the same issue.

The initial framing of this issue was slightly wrong in my opinion, but still I see the usage in the wild and the need for such a case.

I'd like to vouch for a form of post-relese versioning, because:

  • changes to be versioned are not changes to the application sources; the application has a version that is meaningful (i.e. it does not make sense for downstream mantainers to "bump" the version) but an additional information is required
  • build metadata may be used but as they are not considered in version comparison are not acceptable for this use case (1.0.0+1 and 1.0.0+2 shall be considered equal by tooling)
  • post-release versioning is visible "in the wild" and takes lots of different forms, while having the same semantic meaning (from distribution packaging to downstream distribution)
  • the only available solution today that respects SemVer is using pre-release strings, but tools aligning to the spec would require a version bump to work and that would not be compliant

As any standard, the usual XKCD comic applies, but this is probably why having it in SemVer would be so valuable: SemVer is widely renowned and it would greatly help in adoption.

In short:

  • avoid any breaking change is paramount to drive adoption and avoid distrust in the standard
  • this semantic is already in use because is needed, but current implementations usually break SemVer
  • I believe is in the scope and interest of this standard to consider such information as part of the specification, because otherwise the version may lose semantic value

I think there are benefits from "a form of post-release metadata that is considered in version comparison".

@jwdonahue
Copy link
Contributor

@sylr, you'll need to resolve conflicts for this PR to be viable. Otherwise, please close at your earliest possible convenience.

@jwdonahue
Copy link
Contributor

@jeme, I think your spot on in your criticism, given that I think this PR should just be tagged as rejected and closed.

I occasionally make a quick pass through all the PR's and try to get folks to keep them ready, in case the maintainers happen to drop in. We've managed to get a few of them pushed through that way over the years. I am an agitator, not a maintainer. I basically try to get our community to keep the project as clean as possible, because the maintainers do not seem to be very active.

@jeme jeme mentioned this pull request Jun 10, 2020
@FichteFoll
Copy link

FichteFoll commented Jun 11, 2020

Unfortunately, the context of the last comment was lost. I can come to my own conclusion as to what the essence of the proposal was, so to reduce potential confusion by others, I estimate it to be similar to the following: retract and close the PR as "wontfix" due to lack of discussion or input by the maintainers.

While I, too, am quite unsatisfied with how the idea implemented in this PR has been open without a comment by a maintainer for 6 years (I consider #200 to be the start of this discussion), just redacting pull requests due to a lack of response does not help in moving forward. At least not untila general direction for the future of semver has been found.

@mentalisttraceur
Copy link

mentalisttraceur commented Jun 11, 2020

I would assert that

  1. either your "post release" changes the public API in some way, in which case it is directly against the whole purpose and justification of SemVer to present the same major, minor, and patch numbers under the same package name, or

  2. or your "post release" does not change the public API at all, in which case build metadata is precisely the right place for it.


In the meantime, I want to confirm that + is very much in use in the world. I just suspect it occurs more behind closed doors in companies than out in the wild. Open source tends to do... less releases where build metadata is the only thing that needs to change.


Also! We need to stop treating the build metadata as if it is never ever valid to use it for comparison. No. That's not what it means. You have to interpret it in the context of what SemVer does, which is expose information about the public API.

The build metadata "should not be compared" for the purposes of SemVer semantics, because it is meant for things that do not effect the public API.

But the build metadata can, is, and should be allowed to be compared by all sorts of other tooling that builds additional semantics or functionality on top of SemVer. In fact, I would argue that it is not only allowed, but even good practice, to take advantage of the build metadata being compared by higher level packaging tools for version bumps that effect the packaging but do not effect the public API of what is being packaged.

I would even go so far as to say that packaging systems - things whose job it is to actually store, install, and upgrade packages - should be sorting versions by build metadata, and offering those sorted higher as updates.

On the other hand, SemVer parsers - things whose job it is to sort versions only according to what SemVer tells you about the public API - should not compare build metadata.

This gives proper room for multiple "layers" of semantics.


Finally, I want everyone to take a step back from their one pet use case and consider the bigger picture, the general abstraction here: what SemVer is really missing is a way to concatenate multiple SemVer versions together into one version string.

If I had to argue for any change to SemVer, it would be either:

  1. Be explicitly permissive enough with what can come after the + to enable appending another whole SemVer version string after the + (then we can have things like 1.2.3+9.8.7-dev.4.8f67fac+0.1.5-foo).

    -or-

  2. Introduce a new character instead of overloading the + to allow gluing SemVer strings together like that. Maybe the ~ that was suggested earlier?

Key point: as soon as we permit multiple semvers in one version string, we allow for any and all complex usecases where it matters to have this additional versioning information.

Because that third party patchset? That should be semver'ed too.

So 9.8.7+0.0.1 could be used to mean "this is my patchset on 9.8.7, where I have fixed one or more bugs", 9.8.7+1.0.0 could be used to mean "this is my patchset on 9.8.7, where I have made breaking changes", and so on. And then if while your patchset is still in alpha pre-release (9.8.7+1.0.0-alpha), I want to release a patchset on top of it to add a feature, so I release 9.8.7+1.0.0-alpha+0.1.0. And so on. (Replace + with ~ or whatever if we go with option 2 above.)

Edit: actually, a nuance here is that patchset 1.0.0 should probably not mean "backwards incompatible changes have been made to the original", but should rather follow the same distinction that major version 0 vs >=1 has in SemVer, and so maybe the above examples should really be 9.8.7+1.0.1, 9.8.7+2.0.0, and 9.8.7+2.0.0-alpha+1.1.0, respectively.

It would be the job of the release maker to document what each of the SemVers applies to, just as it is the job of the release maker to document their public API to begin with.

@FichteFoll
Copy link

what SemVer is really missing is a way to concatenate multiple SemVer versions together into one version string.

This is more related to #242 than the topic of this PR. I didn't find an open one that relates to this in a quick search.

@alexandrtovmach
Copy link
Member

Closing & re-opening to trigger CI

@alexandrtovmach alexandrtovmach added consensus seeking The discussion is not over yet extend Brand new ideas/rules to add to the specification RFC Request for comments state for next version and removed proposal labels Jun 19, 2020
@mentalisttraceur
Copy link

@FichteFoll I agree that it's more related to that one, but I assert that it is still very relevant to this issue as well, because if my reasoning is correct then this proposal is redundant with a solution allowing multiple SemVers to be glued together, and the latter is a better way than this proposal to solve the problem this proposal is meant to address.

@dcleao
Copy link

dcleao commented Mar 15, 2021

Showing my support for @mentalisttraceur's proposal of composable versions. I believe it solves all of the post-like cases.

I wish the maintainers of this specification would stop what I feel as gatekeeping — against so many, for so long, in the face of so much proof — what they think semver is not for.

I wish some other more practically and generally adequate versioning standard would come up and get momentum. Then, semver would become irrelevant, and would succumb, embarrassed, forgotten, and there would be no more gatekeeping to be done. In history books, semver would be used as a case study, to teach kids how specification maintainers may become blockers to evolution.

Hope is the last to die. So, I will have hope till I die.

@ljharb
Copy link
Contributor

ljharb commented Apr 30, 2021

To be clear, the primary job of a spec maintainer - any spec - is exactly that gatekeeping. The proper way to get something new is to make something new and have it gain adoption, not to make a thing into something it was never designed to be.

@SamirSaidani
Copy link

SamirSaidani commented Nov 17, 2021

I've met the same problem while using semver, and I'm interested in understanding how to deal with this issue while working in the semver framework.

As far as I understand, a solution is proposed in these two comments:

Can’t you assume the next one is a patch, until it’s not? Meaning, use 1.0.1 with a prerelease tag. Just because you have a 1.0.1-build.1 doesn’t mean you ever have to have a 1.0.1 - the next release could just as well be 1.1.0 or 2.0.0.

and comment issue #200 here:

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.

Problem is we lose information: it means that building a pre-release version never say anything about what version you are pre-releasing because ultimately you might not release the actual version you are pre-releasing. A pre-release 1.4.5-dev.3 might end with release 2.3.4.

For instance, I've got the line:
1.4.5
1.4.6
[...]
1.4.15

At 1.4.5 I need to fork because a software is dependent from 1.4.5 and don't intend to update to 1.4.15 but need 1.4.5 updates, so I need now to maintain 1.4.5 as such.

For new dev from 1.4.5, I could use 1.4.6-dev.1 according to these comments, but it makes no sense to me. I could also use 1.4.16-dev.1, but I know that 1.4.16 will never be a release since not related to this new branch. So it means that when writing x.x.x-dev.1, x.x.x has no meaning at all in term of pre-release, which seems to be a problem for a spec focused on "semantic"...

Whereas if I use the post-release mechanism, like 1.4.5+0.1, semantic is restored: the anchor point is real and not fictitious, and the information is saved instead of lost. And I can maintain a whole new branch, for instance 1.4.5+1.0.1 by using recursively semver again on the postrelease part. I might even combined the post with pre-release sign, 1.4.5+1.0.2-dev.1, in a consistent manner.

I might be wrong and I'm interested in understanding how would you deal with the problem I've stated in the semver framework.

@ljharb
Copy link
Contributor

ljharb commented Nov 17, 2021

@SamirSaidani yes, that is the nature of time itself: if you change your mind between a "pre" action and the action itself, then the "pre" action doesn't end up saying anything about what version was actually released.

@SamirSaidani
Copy link

@SamirSaidani yes, that is the nature of time itself: if you change your mind between a "pre" action and the action itself, then the "pre" action doesn't end up saying anything about what version was actually released.

@ljharb Sure, I'm just saying that there is a way to dramatically increase the probability that the pre-release version will be the actual one or to get rid of the uncertainty, by taking advantage that when you already know that you don't know, you just have to think post-release instead of pre-release. Actually we might even work only with post-release instead of pre-release (kinda "dual" semver).

@ljharb
Copy link
Contributor

ljharb commented Nov 19, 2021

@SamirSaidani you can't get the probability to 100%, though, so it's still not certainty - so there's not actually a benefit imo.

@mentalisttraceur
Copy link

mentalisttraceur commented Nov 20, 2021

@ljharb There is a benefit as soon as you can get that probability at least as high as the probability that your official release SemVer string does not have a mistake in it.

P.S. In fact the correct way to figure out the combined benefit of different probabilities is not to treat the lowest probability as putting a ceiling on the value of any higher probability anywhere else in the whole picture. The correct way is closer to multiplying the value of each possibility by that possibility's probability, and then totaling those weighed values. Being uncertain that I won't die in a freak accident any moment now doesn't really cap the value of getting greater certainty that I'll have enough money to pay the bills next month.

P.P.S. More generally, there is no such thing as 100% probability. 100% probability is a convenient fiction and shorthand among mature consenting engineers and philosophers, delusion otherwise. If someone thinks something in the real world is 100% certain, they are wrong, and it is unfortunate that they might be close enough to correct for practical purposes that reality does not empirically reveal their error to them. So a boolean view where only 100% certainty is valuable is actually equivalent to saying that any and all real knowledge that's realistically possible is equally entirely worthless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consensus seeking The discussion is not over yet extend Brand new ideas/rules to add to the specification RFC Request for comments state for next version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet