1. 21
  1. 17

    The key idea around semver is around choice.

    I disagree. The key idea in semver is awareness.

    When I’m bumping versions of a bunch of libraries, I want to know which version bumps are most likely to cause breakage.

    1. 12

      You can’t replace QA with a versioning scheme.

      If you can’t trust people to bump semver-major as appropriate, you can’t trust them to “dont break your API. Make a new thing” instead either. Compatibility and long-term maintenance are hard for reasons other than arrangements of digits in the version tags.

      1. 8

        The feature which is a bug with samver is that every commit has a version.

        A semver requires a human (or otherwise trusted computational process) to declare “this is a release”.

        This is basically a way to recapture svn-style monotonic version numbers for every change to a repo.

        If you want to do that - and require a human to bless a release - asking the human to tag each release with ‘release-N’ for N=1,2,3,4,5,… is maybe the equivalent. It’s semver without the sem.

        1. 4

          The issues listed in this article with semver are why I made ChronVer. I do like samver more than semver though, it makes more sense and ensures adherence to its purpose.

          1. 1

            Similar to https://calver.org/ which is what I usually advocate.

          2. 3

            Besides the issues that were addressed by others :

            12 consecutive digits without punctuation or other visual guidance is hard to parse for me as a human being - and even to compare if they are not perfectly aligned.

            1. 2

              The “standard” ISO 8601 representation has punctuation:

              2020-07-30 10:40

              but that includes a space (can be replaced by T) and colons between HH and MM.

              If it’s just YYYYMMDD I find the lack of punctuation tolerable, but including hours and minutes pushes it over the edge for me too.

            2. 3

              While I agree with the basic premise here I don’t think his idea really solves any problems.

              I feel like the best version scheme is systemd’s. It’s a positive integer. It clocks up by one every release. You can’t mess it up. There never any doubt about which is older/newer. If you’re worried about comparability that’s what release notes or the change log are for.

              1. 3

                Try out Go modules! How many 0.0.0-x-y modules can you find?

                … what? 0.0.0 is a special designation used by the module system to indicate “this is not a release”. Nobody’s typing git tag -a -s v0.0.0.

                Lets use the commit date of the code [and …] add the commit SHA […]

                This is literally what the Go module system uses for things that are not releases. The author, bafflingly, does not appear to be aware of this prior art despite mentioning it earlier.

                1. 3

                  True for Go modules, but I see a lot of the “zeroth version abuse” pattern around. People are using it as an excuse to make breaking changes without deprecation procedures or proper warnings, because it’s 0.x.y, what can you expect? There are projects that stay at 0.x for years despite having lots of users.

                  I believe if it’s used by anyone else than developers themselves, it’s already 1.x, whether developers want it or not, especially if those external users actively give back. They deserve proper warnings when things break.

                2. 3
                  1. 2

                    My main problem with SemVer is that it doesn’t provide a mechanism for gradual deprecation. The GNUstep Objective-C runtime supports two ABIs (well, a bit more, but I’m simplifying):

                    • The v1 ABI is backwards compatible with the old GCC ABI.
                    • The v2 ABI is a big cleanup.

                    Version 1.x of the library supports only the v1 ABI. Version 2.0 of the library can support either ABI. This is not actually compliant with SemVer because it wasn’t actually a breaking change. A future version will support only the v2 ABI. I have, effectively, 3 versions:

                    • A supports ABIv1
                    • B supports ABIv1 and ABIv2
                    • C supports ABIv2.

                    A -> C is a breaking change, but A -> B is not and neither is B -> C.

                    1. 1

                      A supports ABIv1

                      B supports ABIv1 and ABIv2

                      C supports ABIv2.

                      A -> C is a breaking change, but A -> B is not and neither is B -> C.

                      I would argue that B -> C absolutely is a breaking change, in that it breaks anything still using ABIv1. Just because a the change doesn’t affect all users, doesn’t mean it isn’t a breaking change. The only way B -> C isn’t a breaking change is if for some reason you consider using the deprecated ABI to be “broken”, in which case A -> B is the breaking change.

                      1. 2

                        B -> C is a breaking change as SemVer is written, but by the time we release C we’d expect people to have all moved to the v2 ABI. I don’t want to force everyone who has moved to the v2 ABI to re-link their binaries. The problem with SemVer is that it’s trying to encode a range in a value. If I published a range for my library version, each release would have been 1.0 - 1.x, then 1.0 - 2.0, then 2.0 - 2.x, consumers would have a required version like 1.0, 1.5, 2.1, or whatever.

                        1. 1

                          I see your point. Maybe SemVer isn’t made to be combined with overlapping deprecation & new ABI in a single release. What if the overlap wasn’t created by having a single 1.9 release which works with both ABIv1 and ABIv2, followed by 2.0 which is ABIv2 only, but instead by releasing 1.9 (ABIv1 only) and 2.0 (ABIv2 only) simultaneously with the same features?

                          1. 1

                            The problem with that model is that it gives a flag day. I don’t want to force people to recompile just because I’ve released a new version, I want to give them a two-year period to upgrade. Most vendors of widely used shared libraries do something similar and gradually deprecate features so they always have a sliding window of supported versions.

                            As a library consumer, if I compile for the 2020 version, I want to expect my binary to work in 2021 and 2022, but maybe not in 2023, but if I compiled against the 2021 version I want it to work in 2022 and 2023. I don’t want the library vendor to say ‘The first 2021 release is an ABI break, everyone must recompile their code now’.

                            SemVer encouraging flag days is not a great secondary effect.

                            1. 1

                              It doesn’t have to give a flag day at all, in that you can keep supporting the v1 ABI in parallel as long as you want to, with a 1.* release to (roughly) match each 2.* release until you are happy that most of your users have switched to the 2.* series. (I’m assuming that you would release them both from the same codebase, but instead of just marking the v1 parts as deprecated, you add a feature to choose which API to support.)

                    2. 1

                      There’s some overlap here with Rich Hickey’s Spec-ulation talk: https://www.youtube.com/watch?v=oyLBGkS5ICk


                      dont break your API. Make a new thing, name it something else, figure out the migration that makes sense for you and your users.

                      Most Clojure core projects were on 0.xxx until recently, where they bumped to 1.xxx due to the perception issues associated from a world which is mostly SemVer. Most of them haven’t broken API for many years.

                      1. 1

                        The Knuthian TeX versioning is droll, for those who haven’t heard of it: It (used to?) use precision of numbers in pi to increment the version… (from wikipedia of Software_versioning)

                        The current version is 3.14159265. This is a reflection of TeX being very stable, and only minor updates are anticipated. TeX developer Donald Knuth has stated that the “absolutely final change (to be made after [his] death)” will be to change the version number to π, at which point all remaining bugs will become permanent features.