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

[spec] document real-world v0 semantics #923

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ljharb
Copy link
Contributor

@ljharb ljharb commented Mar 9, 2023

Per #915 (comment)

Fixes #915. Closes #916. Closes #127.

Additionally, I notice the document often, but not consistently, hard-wraps at 80 chars. While I find soft-wrapping immeasurably superior for diff clarity and editability, consistency is also important, so I'd be happy to make a separate PR that updates the entire document to consistently soft-wrap or hard-wrap.

@steveklabnik
Copy link
Member

I'd be happy to make a separate PR that updates the entire document to consistently soft-wrap or hard-wrap.

I am unsure how I feel about this personally, we can sort it at some point.

Copy link
Member

@steveklabnik steveklabnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for this.

I am unsure how I feel about it right this moment, but I deeply appreciate starting to tackle this. You took a different approach than maybe I was thinking of, I am unsure if that's good or bad! I am unlikely to be able to devote significant time on this until next week.

@@ -1,4 +1,4 @@
Semantic Versioning 2.0.0
Semantic Versioning 2.1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could argue this means 3.0.0. I dunno. Something to think about. Semver has never really been super consistent with versioning itself. Maybe it's a good time to start that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i figured we'd iterate on this line :-) you could argue this is technically loosening constraints on v0, or increasing them. Making it v3 would certainly be a safer approach.

semver.md Outdated Show resolved Hide resolved
@ljharb
Copy link
Contributor Author

ljharb commented Mar 9, 2023

I'd love to hear more about what approach you were thinking of. No rush; happy to talk about it next week. I'm also available for a video call if that's easier for you.

@jwdonahue
Copy link
Contributor

jwdonahue commented Mar 9, 2023

This is definitely a breaking change. Your favorite packaging tools are not the only bits that depend on this spec. If you are going to ensconce just one convention that was traditionally an allowed overlay on top of the spec, I think you should use mine <grin>.

You seem to be trying to say that 0.y.z is no longer a prerelease form on its own, which was not the original intent of versions 1 & 2 of the spec. Version 2 of the spec and a reading of the FAQ indicate that the 0.y.z form precedes the 1.y.z initial release form. I am sure there are many explanations of this in semver/semver issues and probably StackOverflow showing typical version histories of the form:

0.1.0 // implied prerelease as the API is not defined until 1.0.0.
0.1.1 // implied prerelease as anything might break.
0.2.0 // same here.
1.0.0 // First release.

As far as I can recall nobody ever raised any objections to this in the past. Nothing about the original wording precludes you from adopting your proposed workflow oriented overlays, but no sane external consumer of your product would expect a 0.1.0 version to be complete, build or runtime safe.

@ljharb
Copy link
Contributor Author

ljharb commented Mar 10, 2023

That's correct, and has always been the case, since you can have a prerelease of a v0. v0 versions are and have always been full releases.

@jwdonahue
Copy link
Contributor

That's correct, and has always been the case, since you can have a prerelease of a v0. v0 versions are and have always been full releases.

Which is it? A prerelease or a full release? I do agree that you can also add a -pr tag as well, but that doesn't change the fact that a 0.x.y without the -pr tag is in fact a prerelease.

According to the v2 spec:

  1. Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.

Sounds like a prerelease to me. Initial develop precedes release, so clearly this one form of a prerelease version. Notice there is no 0.x.y in this spec, the author(s) clearly intended 0.minor.patch. The mere presence of the 0 in the major field literally means any publication can contain breaking changes so the same rules associated with the pr tag apply.

But then we get 5 (emphasis is mine):

  1. Version 1.0.0 defines the public API. The way in which the version number is incremented after this release is dependent on this public API and how it changes.

So now we have the definition for a release version which follows the initial pre-release definition. Yet another indication that 0.x.y really is something that comes before the first release, clearly making it a prerelease. Hence this proposed change is breaking and I see no language therein which provides a means for implementors to determine which semantics apply to a particular version string.

Then we eventually get to 9:

  1. A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. ... A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.

This is the second definition of a "prerelease" version and it allows us to go back into development mode without having to drop back to the 0.x.y series. I should point out that having a dev branch perpetually churning out 0.x.y prereleases that land in a series of release branches:

1.0.0 // After 0.7.23 was tested.
1.1.0 // After 0.8.0 was tested.
2.0.0 // Oh maybe dev's are as far as 333.9999 by now.

Isn't prohibited by the spec. While this may not be sound, there's many other potential permutations on this for organizations that do lots of pre-flighting of prereleases in various A/B scenarios. Fixing that loop-hole is technically a breaking change, but unlikely to have widespread impact, especially among the current set of package types represented by the maintainers of SemVer. I've certainly never seen anybody doing this, but there must be tens of thousands of bespoke and ad-hoc implementations in the world today.

I think the spec should stick to the minimum required to define a common syntax and semantics, and leave the tool makers and workflow designers with as much freedom innovate as possible.

@ljharb
Copy link
Contributor Author

ljharb commented Mar 10, 2023

A prerelease is only something with the prerelease suffix - it has no other requirements. It may sound like a prerelease, but it’s still not one. That the things that a prerelease indicates may also apply elsewhere doesn’t mean it’s a two-way implication.

@jwdonahue
Copy link
Contributor

Looks like a duck, sounds like a duck, it's a duck.

@ljharb
Copy link
Contributor Author

ljharb commented Mar 10, 2023

Unfortunately, the map remains not the territory.

@jwdonahue
Copy link
Contributor

Unfortunately, the map remains not the territory.

Ya I was just trying to find Preston's original repo. I remember reading through all of the issues before he handed it off to Phil and they moved the official site here.

@ljharb
Copy link
Contributor Author

ljharb commented Apr 4, 2023

@steveklabnik gentle ping, since it's been a few weeks :-)

@steveklabnik
Copy link
Member

I did not manage to get to this this weekend but I do care about it, my intention is to merge something semantically the same as this, or maybe possibly this, but I need some more time to get my full thoughts down but also didn't want to continue radio silence :)

@ljharb
Copy link
Contributor Author

ljharb commented May 15, 2023

Thanks for the update :-) I'd be more than happy to make any changes whenever you get to describing them.

@ljharb
Copy link
Contributor Author

ljharb commented Jun 1, 2023

@steveklabnik another gentle ping, if you want to take some time away from governance drama <3

Copy link
Member

@steveklabnik steveklabnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, once again, for taking forever. Sadly the governance drama doesn't let me get distracted with other work, it just robs me of the desire to do anything :(

Okay. After sitting on this for a while, and even passing it by @indirect a while back, I am comfortable with the way that you changed this.

The only real question to me is the "semver of the spec itself" problem. Which is its own can of worms. I am not sure the proper way to move forward on that, but I also don't want to block this on solving a bigger issue. Do you have any thoughts there?

@ljharb
Copy link
Contributor Author

ljharb commented Jul 13, 2023

Arguably this is a patch in that it loosens the semantics of v0 versions from “always breaking” to “only sometimes breaking”. You could also interpret it as major because it applies semantics that weren’t there before.

Are there any important ecosystems that don’t follow this already, where this change would break them?

@steveklabnik
Copy link
Member

Are there any important ecosystems that don’t follow this already, where this change would break them?

As far as I know, no, it is purely a "bring the spec in line with practice" thing. but i wish we had better test coverage here.

So I think this implies we should do it.

@FichteFoll
Copy link

FichteFoll commented Jul 13, 2023

It may be reflective of what is used in practice, but semver isn't about "how an API is used". It's about "how an API is defined" and if we consider the rules that semver defines to be the API, then this is definitely a breaking change that requires a major bump.

Example:

With semver 2.0.0, you may include breaking changes in the update from 0.1.0 to 0.1.1. With this change, that would be illegal as any breaking change for a 0.X.y (X > 0) MUST increment X.

compatible functionality is introduced to the public API. It MUST be
incremented if any public API functionality is marked as deprecated. It MAY be
incremented if substantial new functionality or improvements are introduced
within the private code. It MAY include patch level changes. Patch version
MUST be reset to 0 when minor version is incremented.

1. Major version X (X.y.z | X > 0) MUST be incremented if any backward
1. Major version X (0.0.X | 0.X.y | X.y.z) MUST be incremented if any backward
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to prevent overlaps between 0.X.y and 0.0.X, a requirement for X > 0 should be added here as well. Note that this would not cover 0.0.0, which … doesn't really fit into any bucket here anyway. Maybe it should be disallowed?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this would not cover 0.0.0, which … doesn't really fit into any bucket here anyway. Maybe it should be disallowed?

In practice I think I've only seen this used for reserving a name in a registry, not for any actual release. In other words 0.0.0 releases typically don't even have an API yet to version. So I guess the general usage already assumes that 0.0.0 is invalid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why 0.0.0 would be invalid, it's a valid starting point afaict.

Copy link
Contributor

@jwdonahue jwdonahue Aug 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than it being far more likely, that an existing feature could be removed or substantially broken without notice in a 0.y.z publication, I have never treated them any differently than any other prerelease.

I do find it useful that 0.y.z preserves the "feature added" and "fixed bug" semantics, rather than the 0.x.y form that munges patch and feature semantics in y, while giving me zero useful information in x. Our pre-ingestion tests are going to tell me whether something is broken, that's why we run them before we ingest them. We assume breakage, but that doesn't stop us from running whatever tests we can, to continuously track our progress.

Given that this proposed change still allows breakage on the y bump, as consumers, we still have to assume that all prereleases may be broken, so this change in the spec is not an improvement. The fact that we would lose the feature/patch signals, implies a loss of data, hence a step backwards, at least for some of us who pay attention to these sorts of things.

Under the current interpretation of the spec, I know that a passing ingestion test on a y bump is meaningless until I add tests for whatever new features were added or removed. I also know that a z bump should have fixed at least some of the test case failures. I also know that when a non-prerelease 1.x.y is finally released, it's highly unlikely to be a breaking change from whatever the last 0.x.y was. Under the current spec, we don't have to have special logic for two classes of prerelease.

I think that the 0.major.minor|patch and 0.0.major schemes simply allows publishers to claim semantic versioning while never really committing to keeping un-signaled breakage to a minimum, or really signaling anything useful at all. It also introduces the weird inconsistency that the value of major can go from x > 1 to x = 1 with each shift to the left.

I also think that we should not consider breaking SemVer without first establishing how to disambiguate between SemVer 2 and all future versions, including patches and etc.

@Lxstr
Copy link

Lxstr commented Feb 17, 2024

Even setting aside how much transition confusion this would introduce, I think this PR would cause far too much cognitive load when you consider how millions of people use this concept of semver MAJOR.MINOR.PATCH. Even one second extra is thousands of extra hours spent decoding what semver a package is using, maybe guessing based on it's release date and then trying to understand what changes have occurred. Also, having to communicate about changes in a <1.0.0 version
becomes too hard and I suspect you'll get people simply not comply with semver, or semi-comply and use 1.0.0 as their starting point.

Perhaps the problem statement and intent could be clarified, but I suspect the intent is to reduce ambiguity on whether a release is stable or in initial development, and that would be a good idea, but I don't think this is the way to go about it. One idea might be that the Development Status of the product could be more clearly separate from semver altogether. For example Pypi has the underused ability to mark Development Status:

1 - Planning
2 - Pre-Alpha
3 - Alpha
4 - Beta
5 - Production/Stable
6 - Mature
7 - Inactive

Note decisions regarding this are often not made WITHIN a release, the clearest example would be deprecating a package, but you can apply it to the others. You wouldn't cut a new release to mark something as deprecated, you would flag it as deprecated and archive the repo.

I think it would be very neat if this was used more ubiquitously while semver eventually removed the notion of <1.0.0 being initial development. Think of packages that need to make a breaking change but don't consider themselves beyond a alpha status for their product overall. And of course as you illustrate, there are many sub 1.0.0 products that have become defacto Production/Stable, cutting a new release just to indicate the product is stable seems strange.

@ljharb
Copy link
Contributor Author

ljharb commented Feb 17, 2024

@Lxstr this is already how npm (and possibly bundler?) has always operated, and the number of people using npm is quite significant compared to all other users of semver, so I think this would reduce, not increase, confusion.

The intent is to update the spec to match what npm does.

@jwdonahue
Copy link
Contributor

The intent is to update the spec to match what npm does.

That is exactly why this PR should not be accepted. It would impact a large number of valid implementations. There are many other implementations that do not and probably will not conform to how NPM does it. Keep in mind that SemVer predates NPM. There is nothing in the spec that precludes NPM's behaviors, so why change the spec to match what they are doing?

@ljharb
Copy link
Contributor Author

ljharb commented Feb 21, 2024

@jwdonahue what highly adopted implementations would it impact?

@ljharb
Copy link
Contributor Author

ljharb commented Feb 22, 2024

That opinion is reasonable to express about ranges, but I'm not sure why it applies here - again, if you can help me understand concretely how this PR - and only this PR - would negatively impact other adopted ecosystems, such as NuGet, I'd be happy to work on bridging that gap.

@jwdonahue
Copy link
Contributor

I did a search on github for SemVer implementations a few years back. There were over several hundred of them at that time. I would estimate that there are perhaps as many as 10K, or more, SemVer implementations being used in production systems around the world today, mostly in the form of scripts. Most of us do not do SemVer the MPM way.

@ljharb
Copy link
Contributor Author

ljharb commented Feb 22, 2024

It's clear this change would be a "breaking" change in the spec. That's ok tho, because the long tail of implementations are best served by following what the most popular implementations do - that's how standards work, in practice.

@jwdonahue
Copy link
Contributor

@ljharb

...but I'm not sure why it applies here...

SemVer semantics influence baseline selector logic. Last few times I read your proposed changes, they effectively modify the semantics of the version triple. It is a breaking change that further restricts the range of conformant selector logic.

@ljharb
Copy link
Contributor Author

ljharb commented Feb 22, 2024

Yes, that is the point, and the improvement. This PR would need to be part of a "v3" of the spec, surely.

@jwdonahue
Copy link
Contributor

The 0.y.z form, uses the major field to signal that a new version might break something, without requiring the major version bump on each release and without losing the distinction between non-breaking additions and bug fixes. The SemVer spec is built around the mapping between major field indicates breakage, minor field indicates additions and patch indicates bug fixes and the syntax is major.minor.patch. The meaning of each field is fixed, the values are used for sorting and selecting.

@jwdonahue
Copy link
Contributor

jwdonahue commented Feb 22, 2024

@ljharb

This PR would need to be part of a "v3" of the spec, surely.

Might as well call it the NPM version of the spec.

@ljharb
Copy link
Contributor Author

ljharb commented Feb 22, 2024

npm

(and that sounds like a good thing, given that it's the largest ecosystem by any available metric)

@jwdonahue
Copy link
Contributor

jwdonahue commented Feb 22, 2024

Here's a metric for you:

It's just 1 to maybe 5 in thousands of implementations, hardly dominant.

@ljharb
Copy link
Contributor Author

ljharb commented Feb 22, 2024

Number of implementations is irrelevant, anyone can make a hundred new implementations that nobody uses - what matters is the number of users (individually or in aggregate).

@jwdonahue
Copy link
Contributor

Not relevant to you perhaps, but to all of us implementers that gleaned the beauty of the fixed syntax and the specific semantics of SemVer, NPM's barely conforming implementation is of little concern to us. All I personally care about here, is preserving the ability to innovate while honing to the semantics of the SemVer spec. I do not intend to modify any code to cover any version of SemVer that does not offer an enrichment of my own products and processes, any more than NPM is likely willing to adopt any breaking spec changes that do not enrich them. Since they already have this particular feature, it's a wash for them if it is not adopted.

One key feature of SemVer is that it is about as tool-chain agnostic as it can be, while remaining relevant. The spec will become irrelevant to all but NPM users, if this change is accepted.

Since you brought up size repeatedly in this thread, I would point out that the most widely adopted and documented versioning scheme is the version quad that Microsoft uses, and other similar schemes. In Microsoft's case, they are gradually moving towards SemVer for many things, but even there, they do not hone to the NPM scheme for anything but Node packages, that I am aware of (FYI: I am not currently employed or contracted at Microsoft).

NPM doesn't give us the full richness available from the current spec and it's selector logic is complex, so we generally use their SemVer tool for that purpose and just assume that all 0.y.z or 0.x.y or whatever might be in them, are breaking changes and we can't know whether any bug fixes are in it, or whether it's a pure feature addition, so... way more attention has to be paid to the release notes, because the NPM tools don't give us a rich enough selector (despite its complexity).

I suppose the later might be automatable eventually, given the recent advances in AI, but not all NPM packages have accurate release notes. The point is, our tooling works as-is and nobody really needs this spec change, not even NPM.

The shifting fields scheme is well documented here and elsewhere, it should not be included in the spec.

@conartist6
Copy link

conartist6 commented Mar 19, 2024

I am all in favor of these changes being made as a new "npmver" spec, but it would be wrong to eliminate a clear distinction followed by real package authors (myself included) from the semver spec on the meaning of 1.0.0.

Changing the semver spec to make 1.0.0 a meaningless distinction is a regression for this project: it offers no guidance at all on how to handle certain critical decisions in versioning instead offering the choice to either follow the religion of two-digit semver (0ver) or the religion of three-digit semver.

Please please please do not subject your versioning scheme to schism because of React.

@conartist6
Copy link

conartist6 commented Mar 19, 2024

This is the kind of change that destroys meaning that did exist. I created meaning when I authored libraries in accordance with the actual guidance given in the spec, and since packages generally do not declare (in a consistent manner) which version of semver they target, the majority of distinctions between 0.x and 1.x APIs made in good faith with regard to the 2.0 spec would be cast into doubt. In the future it will become hard to know whether a package author was aware of the 3.0 specification eliminating the 0ver distinction, especially given that the 3.0 specification must be applied retroactively in order for it to have the benefit of describing what npm has always been doing.

Comment on lines -70 to -75
1. Major version zero (0.y.z) is for initial development. Anything MAY change
at any time. The public API SHOULD NOT be considered stable.

1. Version 1.0.0 defines the public API. The way in which the version number
is incremented after this release is dependent on this public API and how it
changes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the other changes are OK but the removal of these sections would, in my view, be a serious error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's basically the entire point. The distinction of "v1.0.0" isn't valuable or meaningful, and in practice having it has been harmful.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't meaningful to you, but I'd argue that there are plenty of people to whom it is a meaningful distinction. To me it's the keystone to the philosophy of semver. The spec hints at this heavily when in the FAQs:

If even the tiniest backward incompatible changes to the public API require a major version bump, won’t I end up at version 42.0.0 very rapidly?

The way I interpret the answer is "if there are so many APIs in your package that you're realistically in danger of ending up at v42, you really should have split apart multiple packages with more focused responsibilities".

I think that by making 0.42.0 the same thing as 42.0.0 you're removing the key force the agreement exerts that tends to create strong well-factored ecosystems of code, which in my mind was the largest part of the purpose of this document

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a number, it doesn't matter if you have v42 or v153. Breaking changes should be avoided in every case regardless, but that's an opinion that doesn't belong in this document. (and that doesn't match my understanding of its purpose, which is to safely convey breakage, not to inhibit it)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But v153 does inhibit breakage. It usually means that there are several unrelated APIs inside, e.g. all the helper methods from a utility library, or all the components in a whole design system. Most of the time a bump from v152 to v153 means that 49 of the components in a design system had no breaking changes and one of them did. This is not a situation where semver has failed to protect the publisher but it is a situation where the it has failed to protect the user, who got 49 false positive reports of changes alongside one real change. This is no longer a valuable tool for helping the user understand what has not changed about their own software.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If v3 of the spec is breaking, why not just outlaw versions starting with 0? Wouldn't that solve everyone's problems to their satisfaction? It would be clear that any triplet starting with 0 is not semver v3.

The only problem with it is that it isn't a change that can be retroactively applied without opt-in from the users, but I see that as ideal. The great promise of semver is that it allows you to make breaking changes because people who don't want to be broken have the chance to opt out.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benefit is that it requires no changes at all. Semver already requires versions to be >=1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it doesn’t require that.

Outlawing versions that already exist would be incredibly harmful; that should be a nonstarter.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm saying the spec exactly as written is already correct. These versions are not outlawed in must-not language, the breaking.adding.fixing triplet pattern just doesn't apply to them. To offer that protection you have to opt in by making at least one official release.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that semver explicitly doesn't say what semantics apply to any version starting with 0.x is exactly the freedom you need to be able to solve your problem: defining a meaning for those 0.x version numbers that is consistent with the npm ecosystem's historical expectations (roughly 0.changing.fixing). The only problem I have here at all is the idea that the two things are one document: that your changes overwrite the underlying spec instead of coexisting with it as they easily could.

@conartist6
Copy link

conartist6 commented Mar 20, 2024

So my argument is that there are two versioning schemes: three-digit semver and two-digit semver. They are compatible with each other (mostly) because both agree on using a triplet, it's just that in the two-digit scheme the first digit is always 0.

For this reason I think it's more likely that users will know them as semver and 0ver. 0ver is currently a joke, but if 0ver.org proves anything it's that there's plenty of projects for which the two-digit semver model is appropriate and its usage ongoing. The main problem here is that the site describing this versioning system is a joke, a mean prod at legitimate engineering.

All the projects listed on that site need the ability to have a semver.org-like document that describes the semantics of triplet-using projects that never intend to go to 1.0.0. If we could convince 0ver.org to go up with an actual spec, the primary difference from the semver spec would be the omission of the language about versions <1.0.0 not being "public" releases, the inclusion of the criteria for major and minor in a two-digit release system, and the inclusion of the same basic parsing rules for which strings constitute valid version numbers (with the addition of the leading-0 rule).

@ljharb
Copy link
Contributor Author

ljharb commented Mar 20, 2024

There’s also one-digit, 0.0.x, where every change is breaking. All three are part of semver in the npm ecosystem.

@conartist6
Copy link

conartist6 commented Mar 20, 2024

Makes sense, yep.

There should be a spec documenting one-digit triplets too, and preferably each package should be able to declare (in a discoverable way) whether its intention is to use 1-digit, 2-digit, or 3-digit version numbers.

If this was implemented even one-digit semvers could be made to behave correctly in npm, since the default behavior of prepending ^ will not do the right thing

@ljharb
Copy link
Contributor Author

ljharb commented Mar 20, 2024

why would it be valuable to have three distinct specs that nobody uses in isolation, and all combine to form what the world actually uses? (as opposed to one spec containing all three forms)

@conartist6
Copy link

Are you saying this is something you'd agree with as long as the one spec (semver.org) simply defines one-digit, two-digit, and three-digit variants?

@ljharb
Copy link
Contributor Author

ljharb commented Mar 20, 2024

I must not be clear on what you're suggesting.

I think the only thing that matters is having a single spec that defines how npm works, which this PR plus the ranges PR would do. I see no value in having any spec for "semver but v1+", or for "v0.x.y" or for "v0.0.x" in isolation.

@conartist6
Copy link

My confusion is that to be able to say what constitutes a breaking change you have to know what the package author intended. I thought that we were in agreement on that. Each of the versioning systems in real use use a different digit to denote breaking changes. If you say "the spec doesn't differentiate" then it seems to me you're saying "it will never be possible for users to be protected from breaking changes in all real versioning scenarios."

@ljharb
Copy link
Contributor Author

ljharb commented Mar 20, 2024

Yes, but this specification doesn't address that - something external to this spec would have to point to it, like package.json in npm, or the equivalent in other ecosystems. I would support that if you pursued it elsewhere, after a spec exists that matches what npm has always done, of course.

@conartist6
Copy link

npm has always presented the semver spec as its own ideal -- the idea that packages people depend on should be 1.0.0, that was and currently is npm's stated ideal. How would that idea survive these changes?

@ljharb
Copy link
Contributor Author

ljharb commented Mar 20, 2024

That wasn't always the case, and just because it's the default in npm init doesn't mean anyone is prevented or even discouraged from publishing or using v0 packages.

Thus, these changes would have no impact on anything except to bring this specification into alignment with its most widely used implementation.

@conartist6
Copy link

"It has no impact on anything" is wearing a bit thin when I am describing the impact. You could earn my endorsement though by creating explicit guidance in the language of the specification that describes when it is appropriate to use one digit vs two digit or three digit versions.

@ljharb
Copy link
Contributor Author

ljharb commented Mar 20, 2024

To be clear, all of them are three digits - it's just that the first one or two is zero. Adding "should" guidance doesn't really make sense tho when the guidance is "use whatever version you feel like using" - it's not this spec's place to editorialize about the appropriateness of version number choice, as long as breakage and additions are conveyed correctly by transitions.

@conartist6
Copy link

conartist6 commented Mar 20, 2024

I said my piece. I believe you should write up a spec that has no editorial intent. This spec has editorial intent, and if it stops having that intent it will need to be replaced with (or at least augmented by) one which does.

@ljharb
Copy link
Contributor Author

ljharb commented Mar 21, 2024

This PR does not add editorial intent - it has precisely the same amount as the current spec.

@conartist6
Copy link

My problem is removing editorial intent. Your starting point is a spec with an opinion (major.minor.patch), and at the end you're creating no fewer than three offiically blessed, equally valid ways of doing things and not expressing any preference for one over the other.

@Spiker985
Copy link

Adding my two cents:

I would argue that the V2 spec explicitly defines 0.Y.Z as developmental, and not to be considered stable in any event.

By explicitly defining the rules of 0.Y.Z, I think you're shooting yourself in the foot, as least as written currently.

Just because the npm matcher treats 0.Y.Z as 0.X.Y is not a fault of the spec, but a decision within NPM's implementation.

NPM should follow the V2 as outlined, in that every bump to an 0.Y.Z version, as long as Y or Z have incremented, are potentially breaking changes.

If the author of that software doesn't wish to declare an official release as 1.Y.Z, then it is up to them to relay to their user base that there are no breaking changes - because as per the spec, they should consider every bump as potentially breaking.

Additionally, according to the V2 spec itself, the changes listed in the document would constitute a Major bump as you are explicitly defining (in essence) new ways to handle behavior which would be potentially incompatible with the existing V2 spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Could we clarifies better in the semver doc PATCH releases and initial development?
8 participants