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
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Sylvain Rabot <s.rabot@lectra.com>
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). 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 |
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. |
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. |
There is a lot of "prior art" available here, however. Arch appends a "post-release" number called The advantage of using |
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. |
@jwdonahue The serious DevOps issue you are referring to is called “contributing to open source”. Something your GitHub account shows you know little about. |
@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. |
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 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. |
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. 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 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. Alas, I believe that a backwards-incompatible change like the proposed one is indeed an almost impossible uphill battle against the legacy of the The usage of an underscore |
@FichteFoll, @sylr, please, don't use |
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. |
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 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 Even the discussion of whether the current character that introduces the build metadata 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. |
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 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} 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. |
Dear @jwdonahue,
If I understand correctly what you mean, when According to the proposed post-release scheme, you would, instead, continue development by creating the release 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. |
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. |
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 Yes? Package or interface names can help: P.1.0.0 There are other ways to deal with it. 1.0.0 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? |
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 In the process, you get to occupy the pre-release space of the 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...
Why not?
Simply, because you will be using pre-releases in unintended, dubious ways.
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.
Peculiar way of doing things? You do have a nerve... |
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. |
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. |
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 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 |
Getting adoption of any standard is equivalent to herding cats. |
I agree 😅 however that's different from intentionally ignoring uses cases. Even if, say, |
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 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. |
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 Or we could use the |
I've updated the example, I changed Also added a real life example, the RT patch set for the linux kernel. |
Is anyone implementing this in any of the packaging tools? Particularly those that are owned by the maintainers? |
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 |
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:
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:
I think there are benefits from "a form of post-release metadata that is considered in version comparison". |
@sylr, you'll need to resolve conflicts for this PR to be viable. Otherwise, please close at your earliest possible convenience. |
@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. |
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. |
I would assert that
In the meantime, I want to confirm that 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:
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 Edit: actually, a nuance here is that patchset 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. |
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. |
Closing & re-opening to trigger CI |
@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. |
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. |
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. |
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:
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: 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. |
@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). |
@SamirSaidani you can't get the probability to 100%, though, so it's still not certainty - so there's not actually a benefit imo. |
@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. |
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 ofhotfix
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).