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

Resolve the "what's being versioned" ambiguities in the spec. #468

Closed
jwdonahue opened this issue Oct 8, 2018 · 26 comments
Closed

Resolve the "what's being versioned" ambiguities in the spec. #468

jwdonahue opened this issue Oct 8, 2018 · 26 comments
Labels
question Question about SemVer and use cases

Comments

@jwdonahue
Copy link
Contributor

jwdonahue commented Oct 8, 2018

There's some "how to apply semver to my X" kinds of questions on Stackoverflow and here in the semver project. Those have mostly been resolved by expert advise from various people, but their number indicates some difficulty interpreting the spec. There's also some unresolved issues that mention changing API to package or interface. I am opening this thread to consolidate those into one place with links from here, back to them (perhaps we can close the others?).

You can get a feel for the problem here:

While the titles aren't always on point, I think the gist of the issues comes down to I am versioning an X but the spec says "API" or "Package". Versioning an interface specification using semver is straightforward in most cases because in most languages a change to an interface signature is a breaking change for implementers and consumers alike, but if you interpret interface to mean "collection of language signatures", then any addition to the interface breaks implementers. Packages on the other hand, tend to have at least an interface and an implementation, but they often have explicit or implied dependencies as well.

The semver spec leaves some wiggle-room how exactly you define what your "API" actually is, but the implied abstraction is often missed by the casual reader, who often, if not always, have something very concrete in mind when they see "API", and wetware being what it is, those images vary considerably from person to person.

The semantics of versioning a package vs an interface are naturally quite different. The spec should be adjusted accordingly. It would be natural to simply replace "API" with "interface", everywhere, then provide some example interfaces. In one view; the type, layout and metadata in a package are part of the interface being versioned for instance.

In any case, I think an holistic approach should be taken resolve these issues.

@jwdonahue
Copy link
Contributor Author

Relevant background: https://www.osgi.org/wp-content/uploads/SemanticVersioning.pdf

Discusses consumers vs implementers different views on what is a breaking change.

@ZeroUnderscoreOu
Copy link

ZeroUnderscoreOu commented Oct 10, 2018

As for my personal issue (#314), I'd like the spec to be formulated in such a way (or have a separate section added), so that I could use just like a generic versioning system.
I know that this brings in the problem of defining what a "breaking" change is, because if program communicates only with the enduser, no inside changes are really breaking. But I still think that there is no reason SemVer should be limited from such usage.

@toothbrush7777777
Copy link

toothbrush7777777 commented Oct 18, 2018

If "API" is replaced by "interface", it would be good to specify what "interface" means in this context. Many programmers know an "interface" in the context of various programming languages, not the general computing term:

In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information. The exchange can be between software, computer hardware, peripheral devices, humans and combinations of these.
https://en.wikipedia.org/wiki/Interface_(computing)

@grv87
Copy link

grv87 commented Oct 18, 2018

I agree with @ZeroUnderscoreOu about

use just like a generic versioning system

But I disagree about end user experience.

I suppose we are talking about GUI. Then, when buttons, toolbars, menus, windows etc. are removed or moved somewhere else then for the user it is breaking change. It breaks his habits.
Or, maybe, there is a manual or written instruction to take a sequence of actions. Then that change breaks this instruction or manual which should be upgraded too.

@jwdonahue
Copy link
Contributor Author

jwdonahue commented Oct 18, 2018

UI's of all kinds are used in automation, either for testing the product or driving it to some end. Moving GUI component can be a breaking change for such automation, depending on how it is driven.

While we can almost certainly refine the current semver spec to both broaden its usefulness and refine the semantics, I do not believe any one generic versioning scheme can cover even half the applications that require version tags (think books, plays, digital art, clones, etc). Attempting to do so would be a fools errand. Perhaps we should list all of the intended use cases before we start talking about spec changes?

@toothbrush7777777
Copy link

toothbrush7777777 commented Oct 19, 2018

@jwdonahue I saw that most of the previous issues seemed to be covered by changing API to interface, under Wikipedia’s Interface (computing) definition.
If we take any combination (except human to human) of the defined exchanges, we cover all of the computing-related interfaces very well.

In my opinion, trying to extend the definition beyond that is silly, given that the original goal of Semantic Versioning (at least as I see it) is to communicate compatibility between versions of dependent components, in a human- and machine-readable way.

@toothbrush7777777
Copy link

toothbrush7777777 commented Oct 19, 2018

#341 raises the issue that any change, whether additive or subtractive, to an interface specification is a breaking change for implementers of the specification. I thought that was obvious, but perhaps we some wording to that effect could be added. The specification already states that:

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

This is a question of responsible development and foresight. Incompatible changes should not be introduced lightly to software that has a lot of dependent code. The cost that must be incurred to upgrade can be significant. Having to bump major versions to release incompatible changes means you’ll think through the impact of your changes, and evaluate the cost/benefit ratio involved.

I understand that to mean that you should carefully plan your interface [specification] so that you shouldn’t need to make changes. Of course, you are very likely to have to make changes in the future. But that doesn’t exclude new major versions in the future.

The main issue is that there is a dependency graph of {A, A ← B} ← C. That is, the consumer C depends on or uses both A and B. An interface specification change in A is a breaking change for B, and often a breaking change for C.

In my opinion, an interface specification change MUST be represented by a new major version, since the change is not backwards-compatible. If you are in a period of rapid change to the interface specification, then the version MUST be either 0.x.y or a pre-release major version (e.g. 1.0.0-alpha.203), both of which convey the required semantics under Semantic Versioning.

However, there are languages that allow for a default implementation in an interface specification. With such languages, it may be possible to merely increment the minor version if the additive changes have a default implementation and are backwards-compatible.

@grv87
Copy link

grv87 commented Oct 19, 2018

I think there is a distinction between specification and just an interface of a library.
In the first case I agree with @toothbrush7777777.
But if it is just a library, and its author did not intend that its interfaces or classes would be extended or inherited by user classes then it is the second case, and additive changes are not breaking.

Also, I think that users by default would expect the second case.
Unless it is stated otherwise in the documentation, like this:

This library contains interfaces / abstract classes to be implemented by consumers

or

You could inherit classes provided by this library and use your own implementations

If there is such a mention then it becomes a first case.

Java provides a way to mark class as final so that it could not be extended.
This expresses the second case in code.
However, other languages may not have this feature.

@grv87
Copy link

grv87 commented Oct 19, 2018

On 42.0.0 problem in FAQ, I believe it is formulated incorrectly.
It's not a problem when you very rapidly move from 1.0.0 to 42.0.0 (say, in one day or week). Yes, a few users could be unhappy, but most of them won't notice the difference upgrading from 1.0.0 to 2.0.0 or 42.0.0.
The problem is when you move slow enough to give users time to adopt to different versions in between.

@grv87
Copy link

grv87 commented Oct 19, 2018

@jwdonahue, I agree with you. I didn't think of books (fiction), plays and all other art.
Manuals and technical books, however, fit to semver perfectly.

First, I liked @toothbrush7777777 proposal

any combination (except human to human) of the defined exchanges

But, for the art, process of experiencing the art could be seen as an exchange between the human and the art.
Or, there is an exchange between one piece of art and the others in the same composition, and the design in the whole.
Then what should stop us from using semver for the art?

I see that in order to use semver we have to be able to separate all changes to three groups:

  1. Breaking changes
  2. New features
  3. Everything else

As soon as we able to do so, we could (and should!) use semver.

Or, in other words, we should have two well-defined criteria:

  • is this change breaking?
  • is it a new feature?

Maybe we could build definition based on this?

For the art we can imagine a breaking change. For example, the author decides to rewrite ending completely. But that would be another story, they say. So maybe art do not really have breaking changes, and any seeming breaking change just produces something new, inexperienced earlier.
If we agree with this and with definition based on two criteria then the art could not use semver.
The art requires two-numbering system MINOR.PATCH. And change of the name on breaking change.

@grv87
Copy link

grv87 commented Oct 19, 2018

There is an attempt to use semver for fonts:
https://groups.google.com/d/msg/googlefonts-discuss/w6-i0Opikbc/Lvj-rnCykv4J

A MAJOR version would be after a complete redesign

I tried to use such criterion in my practice for some things, but personally I think this is an abuse of semver.
Maybe we could mention in documentation that complete redesign is not a breaking change, and semver should not be applied here.

@jwdonahue
Copy link
Contributor Author

I wonder if wikipedia is a stable enough reference to use for our purposes here? Attributions are fine, but I think the spec should have a definitions section, and not just a list of links, but the actual definitions intended to be applied in reference to the spec. The question is, should such additions to the spec be counted as non-breaking feature additions or will they actually be breaking changes?

Something to keep in mind is that most of the uses I've seen for semver are packaging tools. Collections of artifacts seem to far out-number pure interface publications. In fact, except maybe for one or two RESTful API's that provide something like a GetInterfaceVersion interface, I am hard pressed to give any examples of uses that do not involve collections of artifacts. Where packages are concerned, manifest content and/or product artifact collection is what's really being versioned. I think the current spec and most packaging tool documentation, tend to get the concepts mixed up.

As #467 points out, there's a stark difference in what constitutes a breaking change, between end users of a library/interface and implementers of interfaces. I am not arguing that the minor field should be designated for breaking changes as they have done, but I think the spec should be explicit how each of the producers, implementers and end-users should interpret changes in version numbers. There's an ordered list of "when you publish this kind of change, bump this field", but not any "if you're an interface implementer, this field bump means X" and "if you're a consumer/application writer, interpret this field bump as Y". Addressing the pure interface vs collection of artifacts dichotomy will add complexity to the spec and probably can't be fully resolved without a major version bump in the spec.

@phil-davis
Copy link

phil-davis commented Nov 26, 2018

In reference to some issues linked here that talk about the software "environment".

When used in a software-packaging environment (e.g. PHP with composer), the various versions of packages used in the "backend" of the software are "sorted out" by some package manager. New versions (patch, minor or major) to be used by the back-end can be happily "sucked in". If the main software can cope with all the things that happened in the back-end without changing its API, then the main software is released with just a patch bump. The release build process has something in place that ensures that all those dependent "back-end" software bumps get delivered to any installation that upgrades. That could be by sucking in all the back-end upgrade code at build time and bundling it with the release, or by the packaging system being available at install time and it sucks in (downloads...) all the dependencies during the install process.

The result of the above is that the main software can rely on being able to automatically force-update those kind of packaged dependencies on every install.

But there are other parts of the "back-end environment" that some software "app" cannot force update. e.g. the supported operating system version, or the supported network cards (or other hardware devices), or the supported version of some programming language used by the software.

The API of the main software is not changing. But if you upgrade to the new version without first updating your operating system, your Java/PHP/... programming language version, kicking out your old network card,... then the new version of the main software may not work.

From the way I discussed it above, it feels like such changes should be a major version bump for the main software. But that introduces difficulty when "back-end environment" "falls off the end of support". For example, you might support your software on 6 different flavors of *nix. Each of these has a different support lifetime and release process. Every couple of months your software stops being "supported" on some old version of one of the *nix flavors. This is simply because the old version of *nix has come to the end of its security patch support. So maybe your software still works on that old *nix, but security patches no longer happen, and you stop running CI against it... If you issue a major version bump every time such "falls off the end of support" happens then you will be pushing out a lot of major versions that actually have no API changes.

Similarly when an underlying programming language "falls off the end of support". The classic case is PHP5.6 that is about to end support. So in Jan 2019 some PHP software will no longer be "supported" on PHP5.6 simply because PHP5.6 "no longer exists" from a security... point of view.

So if you stop supporting PHP5.6 for this reason, then is that a patch, minor or major release?
(All you might change in your code is an install-time upgrade-time check that refuses to install-upgrade on the old version of PHP)

@jwdonahue
Copy link
Contributor Author

jwdonahue commented Nov 26, 2018

@phil-davis, was your post a comment/contribution to this thread or are you asking a related question that you need answered to? If the later, please start a new issue and delete the above. If not, then yes, we need to update the spec to make it crystal clear when/which transitive dependencies factor into the decision of which version number bump.

@ZeroUnderscoreOu
Copy link

One more thing I think I should mention (once again, maybe).

IIRC, originally I started using SemVer because it was required by jpm (before Mozilla migrated to WebExtensions). And that put me in an awkward position where whatever I was developing didn't fall under conditions of SemVer but I was still forced to use it.

My point is, as a widely accepted standard, it's only a question of time for such sort of "leaks" to happen, where SemVer will be utilized in (currently) unsupported conditions because of requirements or simply ease of use.

@phil-davis
Copy link

@jwdonahue My post above is a contribution towards discussion of "what is supposed/expected to happen" with semver major/minor/patch when "backend environment" support changes. That was mentioned/discussed in a few of the threads that are consolidated here.

I asked the specific question:
If you stop supporting PHP5.6 because PHP5.6 has "run off the end of support"?

Because it is a current specific example, and the answer might lead to a more general answer/policy about how to manage the semver version of software when this sort of thing happens.

@toothbrush7777777
Copy link

@phil-davis At least in my opinion, such a change is certainly a breaking change because the end user / consumer of your library can see it / is bound to it.

@grv87
Copy link

grv87 commented Dec 1, 2018

@phil-davis, when environment reaches end-of-life, why you should immediately stop supporting it?
You continue to support it, and run CI against it. Until that time when you want to use some features that require new environment. Or hit a bug in that environment without simple workaround.

Another option is to announce release/support roadmap beforehand and tie your versions to specific environment versions.
For PHP example, you could tie your releases to PHP releases:

Your version First Release Supported PHP versions
2.0 2014 5.6
2.1 Dec 2015 5.6, 7.0
2.2 Dec 2016 5.6, 7.0, 7.1
2.3 Dec 2017 5.6, 7.0, 7.1, 7.2
3.0 Jan 2019 7.1, 7.2
3.1 TBA 7.1, 7.2, 7.3
4.0 TBA 8.0

For OSes:

Your version First Release Supported OS
2.0 Jan 2014 Ubuntu 14, Windows Vista
2.1 Jan 2016 Ubuntu 14, 16, Windows Vista, 7
3.0 Jan 2017 Ubuntu 16, 18, Windows 7, 8
4.0 TBA Ubuntu 18, Windows 8, 8.1, 10

The key point in this approach is an overlap between supported versions of environment. So the user can follow this scenario:

  1. Update your software to new minor version that supports new environment
  2. Update environment
  3. Update your software to new major version

Of course, this has nothing to do with SemVer itself.

@grv87
Copy link

grv87 commented Dec 1, 2018

@jwdonahue, it is an answer for @phil-davis question. My intention was to show that his question (how to avoid frequent major version update) indeed has nothing to do with semver. And, obviously, I've succeeded in this.

On the discussion. It continues for years, with no result. No draft, not even a PR.
I believe that such long discussions lead to nowhere. We need an actual draft to discuss.

There were a lot of ideas already. Including my own in #468 (comment) and other comments. But I didn't get any reaction. So, I'm not sure that even if I make a PR it will be reviewed and discussed properly. Considering how well it is going even with simple PRs here.
There is even no develop/next/v3.0.0 branch to make PR against. Is there a hidden fork with v3.0.0 branch somewhere? Or we consider such change of SemVer itself not as a breaking?

On Wikipedia: although English branch is stable enough, it is not enough for more-less formal specification. Additional links should go in FAQ.

@phil-davis
Copy link

phil-davis commented Dec 2, 2018

@grv87 I agree with your analysis. In the case of the PHP example, it seems clear because some example software X would absolutely depend on PHP. So that is a case where, even though there is NO front-facing API change for software X, there is a back-facing API change, the use of the back-facing API (the syntax/features of the PHP language) by software X has changed in a way incompatible with some older version of PHP. Software X is incapable of automatically implementing an upgrade to the PHP back-end, so it flags this by version bumps. Whether or not this is "nothing to do with semver" is a moot point, IMO. If software X is publishing version numbers, happens to be trying to use semver, and also feels the need to issue a new version because of the PHP change, then the authors of software X have to decide what to do with their "semver-compliant" versioning scheme for this situation.

IMO changes to OS support are more difficult to know what to do. Software X might be running on 10 different flavors of *nix, all of which have varying official support schedules and software X is, in practice, likely tested more thoroughly on some flavors than others... You probably take the "practical" approach and "try not to do anything that you know will break OS-compatibility" in a patch or minor version bump.

@jwdonahue I put my comments here because I found (what I think are) related issues that had been closed and linked to this summary issue. If you want, I can make a separate issue for discussing "back-end environment" versioning.

@jwdonahue
Copy link
Contributor Author

@grv87, apologies for not making the connection. I've been a little burnt out lately, especially when it comes to semver. I was planning on getting around to proposing final language for 2.x.x and adding a proposal for 3.x.x, but got pulled into a paying job, so I'll be mostly ignoring semver from here on out. What I will be doing with some of my free time is working on tooling for VersionMeta and VersionSchema. Trying to get to where I can demonstrate its use for a semver 2.0.0 tag. Then I think it can evolve into a set of standard schema that cover a range of requirements.

As per my own personal rules, I'll close out this thread. I won't have the time or inclination to issue a PR.

@jwdonahue
Copy link
Contributor Author

And yet another discussion on this topic: #716

@cubuspl42
Copy link

@jwdonahue I'm sorry to hear that you won't have the time or inclination to issue a PR, but I respect that. I'm not sure if I understand your personal rules regarding closing issues, though. Multiple issues got closed in favor of this one, so it collectively represents doubts and problems of multiple individuals. I don't believe that in such case it's a good idea to just close this, when nothing actually got fixed and there's no argument that there never were any problem(s) at all.

Would you consider re-opening this issue?

@jwdonahue
Copy link
Contributor Author

@cubuspl42 It's ironic that a cabal of packaging tool maintainers control a semantic versioning spec, that defines an API versioning scheme that really doesn't say a lot about how to version collections of things. Semantic versioning is a concept with many nuances that could not possibly be described in a single page of text. SemVer is just a one page distillation of that concept, that happened to get picked up and promoted, more like a meme than an actual standard.

I have come to the conclusion that SemVer promoted an important advancement for software development, but it's nearing the end of its shelf life. I don't have time for it. It wouldn't make any difference if this issue was opened or closed really, but I spent a lot of time in the past getting folks to close out issues here that weren't ever going to get any traction, so I closed it.

That said, I think there is room in the world for a bunch of new SemVer Application Spec. When not gainfully employed though, I am working on something much more generic than SemVer.

@cubuspl42
Copy link

@jwdonahue
I think that it's not as bad as you suggest. I do agree that's Semver is not perfect for all uses and does not solve all problems around versioning, but I still find it a progress over version numbers that had absolutely no meaning and everyone was making up their own scheme. I believe that some minor wording changes around the term "API" could improve it a lot, though.

If you have a blog post or article regarding those nuances (and issues of Semver), especially if accompanied by real life examples, I would be interested in reading it.

@jwdonahue
Copy link
Contributor Author

I believe that some minor wording changes around the term "API" could improve it a lot, though.

You're welcome to issue a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question about SemVer and use cases
Projects
None yet
Development

No branches or pull requests

7 participants