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

Clarify points 4 and 5 in Semver 2.0 #490

Open
ajbogh opened this issue Jan 29, 2019 · 2 comments

Comments

Projects
None yet
2 participants
@ajbogh
Copy link

commented Jan 29, 2019

Many people seem to be having semantic arguments over points 4 and 5. Specifically, when should the API be considered "released for the public", or when is it best to define version 1.0.0?

I've had numerous conversations in which a project that is pre 1.0 but is already released for public consumption. I personally believe that this project is not using Semver correctly (per the intent of Semver), because it's a public API which should be at 1.0.0. Their argument is that the project is using it correctly because it's pre 1.0 and they're allowed to break the API at any time, even though it's already released for wide public use.

  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.

I believe the intent is that anything pre 1.0 is considered "beta" software, and is not intended to be used in production environments, or used by large organizations that have a requirement of stability. However, people assume that a project can choose to never use the 1.0.0 version number and get away with any sort of breaking changes, even after releasing the code to the public, documenting the API, and gaining a following of users.

There is also the idea of appending '-beta' to the version number, even if it's pre-1.0, to get around the idea of instability in development code. I believe these suffixes should be allowed, but not to avoid eventual major version changes. Perhaps some rules around suffixes should be in place, such as they are only allowed for major versions, not minor or patches. Perhaps a predefined set of suffixes should be created as well ("-rcN", "-beta", "-alpha", "-customTagXYZ"). (not really relevant, please ignore)

This is how I would change the text to avoid confusion and semantic arguments regarding when and how to use pre-1.0 and post-1.0 version numbers.

  1. Major version zero (0.y.z) is for initial development. Anything MAY change at any time. It is not recommended for the public to use 0.y.z version numbers. The project should release a 1.0.0 version when it is ready for the public to use.
  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 as defined in the PATCH, MINOR, and MAJOR sections.
@crdrost

This comment has been minimized.

Copy link

commented Feb 11, 2019

You seem to have specified several goals here and I am curious as to which one is the main or "true" goal. Are you looking to stop people debating over points 4 and 5? Are you looking to change projects which are in your opinion abusing this feature of semver, so that they release major versions? Are you looking to get fewer people using projects at version 0.y.z by indicating that they are not "public"? Are you thinking about this from a package-maintenance context like the semver maintainers are ("when is it safe to upgrade a package? never, if the first digit is 0.") or from some sort of other context, and what is that other context? I'd like to understand your needs better as I think anyone saying "this project implements semver" probably means that aspirationally rather than explicitly; they probably have shipped a breaking change with only a minor bump out of ignorance about some circumstance which is broken.

I'd also like to call attention to something of a larger question here, and it's along the lines of xkcd's "Workflow" comic: what I like about semver is that it makes some sort of oblique reference to a specification for how the software should work. One would want the specification to say that version 1.0.0 should be released when this specification has stabilized. Once we open dialog about specifications we start to talk about a sort of semver "formal semantics." And the reason that I'd be interested there, has to do with versioning something that is not explicitly depended upon by other software. For example, how might you apply semver to an app, or a game? Is a texture update "minor" or "major"?

So, what can we say about the formal semantics?

  • A specification does not exist for 0.y.z releases. What is the most broad notion of a specification? Maybe this: that a specification should essentially concern "requests" and "responses" to those requests, and should state that certain requests are errors and certain information is guaranteed in a response. Those are approximately independent: "This is an error but I guarantee this sort of response" is the definition of a deprecated component, no? Then one could alternatively state that 0.y.z releases have the null specification: the one by which all requests are errors and thus any responses are formally undefined behavior. One could argue that maybe 0.y.z releases are all "deprecated" -- that is, there may be some sort of information guarantee but it may all be formally an error -- but I think that might be pushing the language too much.
  • There are three sorts of software updates: (S) those that change only the specification, (C) those that change only the code, and (SC) those that do both. Semver as it stands right now demands that C-changes must only increment the patch version, while S and SC must at least bump the minor version and may bump the major version: which one gets bumped depends on the nature of the specification change; if requests that were formerly in error are no longer in error, or information is only added to the existing responses, or requests have been marked deprecated, we consider these "non-breaking" and increment the minor version. Any other change to the specification triggers a major version increase.
  • There is a constant desire to add some sort of "generation" or "epoch" and thus transition semver towards PVP. One could state that this is a desire for a sort of meta-specification or "vision" of a product, the idea of specifying what direction the specification is evolving towards. "Foo solved the problem of TypeScript+OpenAPI routing for HTTP engines, but the core of the Foo engine is a TypeScript type evaluator that allows some types to be symbolic expressions which resolve into other types. Some people are depending upon all of Foo to use our type evaluator, even though they do not need the HTTP routing. We are releasing Foo2 which is ONLY the HTTP router, and Bar which is the type evaluator, splitting this into two packages." (I actually think that a formal semantics for semver would discourage adding this because it is much more nebulous to define in that way, but it's interesting to think about how one would formalize that sort of change.)

Just my two cents -- this very much only concerns the first bullet point but I see this question in that more specific context where one is trying to be clear enough to say what I think you want to say: "projects SHOULD release a version 1.0.0 as soon as there is any 'request' which should not be considered an error."

@ajbogh

This comment has been minimized.

Copy link
Author

commented Jul 9, 2019

Thanks @crdrost, I've crossed out the section where my mind was rambling and the ideas didn't add to the discussion or make a strong point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.