Hacker News new | ask | show | jobs
by kylecordes 2370 days ago
As with many projects using semantic versioning, the major version bump just signifies there are some breaking changes. Most projects will just switch from 1.x to 2 work noticing.
4 comments

I can’t understand why the Bazel team hasn’t learnt from Go team how to handle breaking changes. Bazel is an amazing piece of tech, but it can definitely be a lot of work to keep up to date.
I don't know the team specifically, but I suspect the difference comes down in part to Go open sourcing early in development, thus finding a bunch of the rough edges that exist outside Google's walled garden early in the project's life when there wasn't much compatibility _to_ break. Blaze was a mature project within Google for years before Bazel was opened up. Many of the breaking changes seem to be taking one-offs built for features within Google (e.g., the handling of protocol buffer rules) and building those in terms of more general and composeable features.

The net result is a Bazel (and Blaze) that are less burdened by the baggage of legacy, but the cost is a faster treadmill to keep pace with changes.

> The net result is a Bazel (and Blaze) that are less burdened by the baggage of legacy, but the cost is a faster treadmill to keep pace with changes.

(I work on Bazel.)

This is accurate. A few of the biggest breaking change themes are:

1) Converting functionality linked within the Bazel binary into the extensibility mechanism implemented in Starlark. An example includes converting the native Java, C++, Android, Python, Protobuf, Obj-C and packaging rules into rules_java, rules_cc, etc. Many languages now are already implemented exclusively in Starlark. See rules_scala, rules_rust, rules_go and rules_haskell.

2) Starlark and Build API cleanups that accumulated over organic growth and development within Google for the past decade.

3) New build system features to support seamless integration with other build systems and package managers.

What's the Go strategy? Just never have breaking changes?
Don’t break, wait. After a decade revisit.
That "changed some corner cases that likely won't affect you" and "rewrite it all" looks the same in SemVer makes it next to useless, not that any other system would be better. We just shouldn't have any expectations about version numbers conveying much information.
How is SemVer next to useless? The major version bump informs you that you should go look up what breaking changes have occurred before you upgrade. It is inherently useful for under-approximating the "safe" range of versions of a piece of software that can be used, which is seen in practice in many package managers.

That it can't differentiate between those two cases is because it's not meant to. It's like complaining that the blurb of a novel is "next to useless" because it doesn't tell you the complete story in a detailed way over several hundred pages.

SemVer isn't useless because of major bumps, but because of the minor and bugfix.

Theoretically every version change can introduce a bug, which leads to an implicit API change and as such require being a major version bump.

Also, fixing a bug can also introduce an API change, because the API can behave differently with and without the bug.

SemVer just covers the intent, not what's actually happening, which makes it kinda useless in most scenarios. I guess Elm gets it right, tho'.

> SemVer just covers the intent, not what's actually happening

If I say "I'm leaving the office to get a sandwich", that statement only covers my intent. If I then sprain my ankle badly, my statement doesn't say what's actually happening.

SemVer has this flaw because it is a way for a human to say "this change does not introduce a change to the API" and that human can be wrong. That seems to me not useless, it just means it is only useful for projects who are willing to trust the maintainers of your dependencies to avoid being wrong about introducing bugs.

--------

It seems like you're arguing that a project which uses a dependency should:

1) Have humans check the dependencies anyway.

or

2) Wire up their automated test suite to something which can record calls to the API of the dependency and the results of those calls. Turn the record of those calls into an set of API contract test cases. Then, on any version bump (minor, major, or patch), run those autogenerated test cases on the new version.

... I think option 2 might be a good idea? It could be a required reviewer for any dependabot PR.

Yes, and this is my biggest frustration with semver. it adds something valuable by communicating breaking changes, but it loses something else valuable, signaling the magnitude of the changes.

Hopefully in the coming years something will eclipse semver which solves both problems sufficiently. I don't know of any candidates offhand though.

Don't know how you could reliably do it.

You could do something like "LoC from last version" + SemVer.

So, 1.2.3k to indicate Major 1, minor 2, 3k lines of code changed from 1.1. It would also possibly be a good way to say "2.0.3" meaning, we moved from 1.2 to 2.0, but only changed 3 lines of code. The breaking change is likely not going to affect you but it is there.

That might make magnitude changes easier to communicate.

I'm not sure how useful this would be for automated build tools though. Would you set bounds on how far drift would go before automated updates?

Semver provides low resolution data on the nature of a change in a release in an easily comprehencible format.
It's just a few config flag flips.

This is a bizarre naming. They could call it Blaze installer 2.0 for Blaze 1.

(I work on Bazel)

This is how Bazel rolls out incompatible changes:

- Introduce a new behavior behind a flag

- Wait

- If there was no push back (and key projects could migrate), flip the flag to enable the new behavior by default.

The goal is to give an opportunity for users to update their code in advance, and get feedback about migration issues.

Bazel 1.0 was released on October 10. Not much more than two months ago. At best, semantic versioning expresses the intent to break existing code. It's an anti-pattern. It's not a feature. Projects using semantic versioning are explicitly caveat emptor.