26 comments

[ 2.7 ms ] story [ 67.6 ms ] thread
See https://github.com/mojombo/semver/compare/v1.0.0...v2.0.0 for the changelog.

Edit: Changes, that is, not a changelog.

I don't think that's a changelog. That is a collection of git commits, where the intended audience is primarily the developers of the work.

A changelog, by comparison, is meant for clients who use the work.

See also https://github.com/mojombo/semver/issues/387 and http://keepachangelog.com/en/1.0.0/

Yes, you're correct, it's not a changelog - rather, it is the changes.

Click "Files changed" for an actual diff. I am not sure what makes it v2.0.0, however.

Are there any projects that follow this specification strictly? It seems like most projects are willing to do backwards-incompatible "bug fixes" to the behavior of their API without incrementing the major version. These are usually harmless in practice, but technically break rule 8. It seems difficult to me to prove that any given set of changes can't break someone else's code (even allocating an extra byte of memory has the potential to do this).
"Public API" is the key part of #8, not just any change that consumers could find if they tried. Is the exact number of bytes your project consumes part of the public API? If it is (and I doubt there exist many projects that would guarantee that), then yes it would be breaking.
The problem is, that maintaining a stable API seems like not being that easy. Especially in open source projects where most of the people spend their free time and it is easy to make a tiny mistake to break an API.

You asked for specific projects. I can mostly speak for the JavaScript community where React seems to be the best example. They even try to maintain compatibility between two major versions, and give good deprecation warnings. Other big projects like lodash, webpack and RxJS seem to handle it good as well.

As I mentioned, React handles the migration path really well. Other projects do not provide such an easy migration between major versions...

In the unfashionable PHP world the Packagist libraries tend to be very strict about following semver.
Do you have specific examples?

Given that any idiot can publish a packagist library (Hello!) that's kind of like saying "The code on GitHub does".

I'll start by saying Symfony seems pretty good.

I have a specific example of one that bit me recently using Laravel, which has these doctrine dependencies upstream. On my mac I'm running php7.1 because it made sense as most of the code I write is served there now finally but there are some major projects stuck on 5.6 servers. As such I was recently bitten by this: http://doctrine-project.org/2017/07/25/php-7.1-requirement-a....

There about 7 packages listed there. Each github repo has at least one closed issue about this change, likely spurring the article. Knowing the fix of 'pinning' my platform to 5.6 is such an easy fix but what I had to Google to get there absolutely was not.

I feel in this instance that the concept of a platform dependency like PHP is or say the underlying Node.js engine is wildly different than an upstream library. The solace I get with node is often the jump from say 4 to 8 breaks a ton of shit. The jump from PHP 5.x to 7.x breaks exactly none of my code. I believe if it had I wouldn't have jumped to it so eagerly, even though PHPStorm does a wonderful job at keeping me from using 7.x things when I specify a project is 5.6.

I ultimately recognize now that I am the one that put myself in this situation but I feel like library maintainers could do a better job to prevent me from shooting myself in the foot. I know now to pin to very specific major.minor numbers at the very least and proposed that Laravel add the platform config flag to save other similar developers from making the mistake. The problem wasn't that just Laravel pinned to 1.* but that doctrine's own common package did it as well. If the platform config option didn't work another choice was to pin the specific version of upstream packages in Laravel's composer.json. That version of the fix feels like I'm ignoring most of the benefits composer was supposed to give me in the first place. I know the node ecosystem can suffer a similar fate just as easily but it feels really dirty to be in that situation. I start to wonder if I shouldn't be using those packages at all.

I feel like a lot of things, at least in ruby world where I mostly work, have gotten a _lot_ better in the past few years.

"Strictly"? Well, backwards compat mistakes can happen, but mistakes can always happen. Other than that, it's the difficulty of knowing what is the "public API". It's a time-consuming and difficult task to be clear about this. But I think semver has spurred people to try harder and get closer.

The thing I find most frustrating about semantic version is that even under the strictest adoption it overly legitimizes breaking changes across major versions.

I see far too much refactoring of JS library APIs that is essentially aesthetic across major versions - D3 and Angular spring immediately to mind (I understand the scalability justification for Angular; I just don't really believe it).

To me, having an elegant API is not the highest concern because what I'm interested in is building products, and from that point of view stability is much more important. I do not appreciate a committee of J Random JavaScript Developers randomly dumping extra work into my product backlog because they didn't like the cut of an API's jib, especially when these people have gone absolutely out of their way to drive adoption in the first place.

To give a counter-example: .NET code I wrote in the mid-noughties whilst working at Red Gate still runs today, substantially unmodified. Some of that stuff is 11 or 12 years old. SQL Dependency Tracker is the most obvious example, because the product hasn't changed much since 2006, except for additions to support new object types in new versions of SQL Server. The fact that new .NET versions haven't broken the product has obviously made it much easier to support through the years.

That is the entire point of the major version. The fact is, developers sometimes make breaking changes (sometimes for good reasons, sometimes for bad), and we want a standard way of documenting that. If you don't make breaking changes, than stay on 1.X.Y forever. If your project is only a year old and already on version 10.0.0, you are probably doing something wrong; but at least documenting it in your version numbers.
Certainly take your point, and maybe it's in part down to my background, where a new major version generally includes some large chunk of new functionality (regardless of whether or not there are breaking changes).

And really I suppose you don't ever need to go beyond version 1.x.y. Window Maker is quite a good example of this: latest version is 0.95.8 after 20 years of development.

What in the world does this complaint have to do with SemVer?

If a library owner changes their API, all SemVer does is make sure you know about it. Are you saying that if they didn't follow SemVer they wouldn't change their API?

I said it in the first line: it encourages and legitimises breaking changes. You could argue that all it does is provide a framework for managing versioning in the presence of breaking changes but that isn't what I see.
I think you have the cart and horse the wrong way around. SemVer doesn't say that it's okay to break compatibility in major version updates, it defines "major version update" to mean "any update which breaks compatibility".

If a piece of software hasn't broken compatibility but still wants to tell people they've passed a big feature milestone, it's perfectly reasonable (and I think explicitly encouraged) to have separate user-facing and semantic versions - so you tell people it's "Foo 2.0" but publish it to npm as foo@1.37.0. This is right and proper because the semver number exists solely to describe whether an update adds features and breaks compatibility or not; anyone using it otherwise is misusing semver.

I've been at so many companies where someone is pushing to adopt semantic versioning without actually following step 1 in the spec...

> 1. Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it should be precise and comprehensive.

SemVer doesn't even make sense if you don't have a public API. SemVer doesn't make sense for end user products that don't have an API. I really wish people would stop trying to abuse it.

(comment deleted)
I'm pretty sure they mean "API" in its true sense. An API for a module or a library, not necessarily a Web API. It's not unusual for an organization to maintain several projects/libraries/services that interact internally via their APIs (sometimes over HTTP, sometimes directly as a library), SemVer makes perfect sense for this use case.
Yeah, which is fine if that's what you do. You can take 'public' to have whatever meaning works for you.

I'm talking about places that try and apply SemVer to their consumer facing product, that has no API. That doesn't make sense.

They mean API in the sense of anything that someone can declare a dependency against.

Whether it's a web service or a library is immaterial; the point of the thing is to be able to update something and formally tell any downstream dependencies whether the update breaks compatibility or not.