1. 37
  1.  

  2. 9

    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.

    I think maybe there’s a typo here? Should this be Monotonic Versioning, not Semantic Versioning?

    1. 11

      Aaaaaaaaaand 1.1 is released.

      1. 6

        It looks like copy paste from the Semantic Versioning page (semver.org) for the first few rules. Oops.

      2. 7

        Am I understanding correctly that the release number doesn’t reset when the compatibility number goes up? So you could have eg. 1.0 → 1.1 → 2.2 → 2.3 → 3.4?

        1. 6

          Yes:

          The release number SHALL NOT ever be decremented.

          This means you may end up with 4.314, if you release often enough.

          (Why the author/s decided to mix MUST and SHALL is beyond me – MUST & SHALL mean exactly the same thing as per RFC 2119, so mixing it just confuses the reader in that there might be a difference.)

          1. 3

            Sorry, purely that it sounds a bit better in English and the meaning is not affected.

        2. 6

          We need something like this.

          Too much version-standardisation feels “enterprisy” and otherwise uncool, and yet software versions are more than just silly: they feel like a high score, and part of your marketing instead of what it is: a failure on the programmer to get it right.

          Maybe a solution is to make version numbers that count down instead of up, but that might be too heretical. “Versions spent” is good as well.

          I also don’t know how I feel about the metadata. I feel like it should be defined better, even if it’s “this is where your guff goes”.

          FAQ #4 is written very badly, and it’s very important to get this right:

          If people are working around your bug, it’s your documentation that’s wrong, and if you want to change it you need to bump your"compatibility version". The advice you need to be giving here is “don’t surprise your users,” not, “use common sense” because remember: “Common” sense is how we got here.

          Some other things that I think about:

          • Urgency: How important is it that I upgrade? I feel like the difference between version 1.5 and 1.6 is the same as the difference between 1.6 and 1.7 and yet maybe it shouldn’t be.

          • Forwards-compatibility: If I create files with the new version, am I cutting myself off from old versions?

          • API is too narrow because configuration files are also part of your public interface. Look at how mbsync 2015 and mbsync later 2015 have subtly changed making it impossible to have a single configuration file that works across versions. Madness!

          1. 2

            I tried to address FAQ #4 in 1.1 (same URL)

          2. 5

            A normal version number MUST take the form X.Y where X, Y are non-negative integers, and MUST NOT contain leading zeroes. X is the compatibility number and Y is the release number. Each element MUST increase numerically. For instance: 1.9 -> 1.10 -> 1.11.

            This seems similar to Apple Generic Versioning for dynamic libraries. There two versions are used: DYLIB_CURRENT_VERSION and DYLIB_COMPATIBILITY_VERSION—the former corresponds to Y and the latter to X in this post. I do like that both the release and compatibility versions are coded into a single unit.

            I echo @halosghost & @bpo’s concerns about the overly restrictive set of characters allowed in the optional metadata, but overall I do like this.

              1. 3

                This seemed weird as heck at first glance, but I kind of like it. Also, in chat, @asthar linked this example that made it pretty instantly obvious (though I can’t tell what the various arrow styles are meant to convey). I think something like that would be very valuable on this page.

                Typo, section 4.1:

                will surprised

                should be “will surprise”

                One bug, section 3.7:

                immediately following the release number or SemVer patch version

                This scheme does not include a SemVer patch version. I think this is an incomplete edit.

                One concern that I think is probably a misdesign, section 3.7:

                …Identifiers MUST NOT be empty. Examples: 1.0+001, 1.0+20130313144700, 1.0+exp.sha.5114f85…

                Yeah, I kind of instantly want to do 1.0+[gitsha1here], but section 3.8 says:

                Precedence is determined by the first difference when comparing each of these identifiers from left to right as follows: compatibility, release, metadata. Compatibility and release are numerically compared, where a larger number denotes a higher precedence. Metadata is compared lexically with the later sorted values having precedence.

                And that leads into some bad territory. Say I cut version 1.1 with commit 5abcd. Next commit is 2dcba and it fixes a bug but doesn’t cut a release (because the project is on a release train or other schedule, doesn’t seem worth it, etc.). A user builds from source and reports “I have a bug in 1.1!” and I say “That’s fixed in 1.1+2dcba or the upcoming 1.2” and they say “I have a later version, 1.1+5abcd and the bug’s still there!” Woe ensues.

                I think if you either need to explicitly say either:

                1. Being freeform, identifiers are not taken into account for precedence, sorry.
                2. Identifiers MUST lexically sort, so you better make the first identifier a zero-padded count of the number of commits already in the repo or UTC millisecond timestamp with a perfectly synchronized clock because 3.8 basically assumes you did.

                I think #1 is a better choice. The distinction between “metadata” and “identifiers” is pretty fuzzy and I would think of the whole “1.0+foo.bar” as a version identifier and this use confuses me. Additionally, the part where metadata is “a series of dot separated identifiers” means you can’t drop in anything that looks like a typical semver/marketing version number because “3.0” is actually two identifiers “3” and “0”. I think - would be a better separator if you’re married to structuring metadata.

                1. 1

                  Thank you, released 1.2, along with @asthasr’s image.

                  As we discussed in chat: I understand the metadata issue, I think 1 is probably the best solution, assuming that 1 results in an error. But I think forcing errors on software is really hard, so having the ordering be well-defined, is a reasonable compromise.

                  1. 2

                    Yeah. And the gist of why I lean towards #1, for anyone else reading, is that I fear the corner cases will lead to bugs. I’d rather see metadata ignored; the code that compares two versions can return greater than/less than/equal and either also return “equal but for metadata” or offer a method for explicitly checking for that case. The former is nicer with an ADT; the latter is more portable.

                    Really fun conversation painting this bikeshed. :)

                2. 4

                  I deeply dislike how both this and SemVer 2.0 require that characters in the string must be ASCII-only.

                  It’s the 21st century folks; how is it we are still so tied to ASCII?

                  1. 11

                    …besides digits and hyphens and full-stops, what did you want in your versioning system?

                    1. 9

                      e.g., the use of an actual α instead of a. Or, for example, non-arabic numerals for those not programming in English-speaking countries.

                      1. 3

                        Do you have a set of Unicode category properties you’d like to see? Might make for a nice PR.

                        1. 4

                          The language of commerce was once Arabic, the language of Chemistry German, of fields of mathematics Russian…I think it’s only reasonable that the language of software development be English.

                        2. 6

                          The optional metadata in the spec allows more than digits and hyphens and full stops. Consider the ‘unstable’ in 0.9+unstable. Requiring the appended identifier to be ASCII-only is needlessly restrictive to non-ASCII-based languages. UTF-8 has solved this problem well (since 1993) and sorts just as easily lexicographically.

                        3. 9

                          Because both this and SemVer are designed to provide reliable information to automated systems, simpler systems tend to be more reliable, and a good way to limit implementation complexity is to limit the complexity of the inputs the system must process.

                          ASCII has the advantage of being very simple, widely implemented, and broadly compatible with non-ASCII systems, so it’s an excellent choice for machine-readable data.

                        4. 2

                          Since the spec forbids the use of leading 0s, does anybody know of an http server that sorts file listings numerically?

                          1. 2

                            Just start you first compatibility number at 100000 :)

                            1. 1

                              Apache has done this since 2000 via version sorting in mod_autoindex.

                            2. 2
                              1. Why is there no pre-release versioning in Monotonic Versioning? - The pre-release behaviour of SemVer offers little semantic information about a release. Rather than pre-releases, Monotonic Versioning simply increments the compatibility number when a release breaks compatibility with an existing one.

                              2. What if I want my API version numbers to be low? - That is silly, aesthetics have little place in versions where the point is to convey semantic information. If you want lower version numbers, get your API right earlier.

                              If my interpretation of these points are correct, I’m not sure this lends well to public API experimentation. You could easily reach 10+ whilst experimenting with an API design in public.

                              Beyond this, I’d like to have some space for API experimentation in public. Perhaps I could just decide that +alpha or something, may have breaks between release numbers, and make that clear for my usage of MonoVer.

                              Maybe this is just aesthetics though, and I’m just thinking in old-fashioned SemVer brain. I’d love to be enlightened though.

                              1. 5

                                You could easily reach 10+ whilst experimenting with an API design in public.

                                Why is that bad?

                                1. 1

                                  I’m not sure it is. I think it’s my view on aesthetics. SemVer brain, I’ve not really used much else.

                                2. 1

                                  I had the same feeling, but then taking a step back, I wondered how much of the API development would actually be done in public? Seems like most of my testing is internal or with a few clients, at which point I’m not making any compatibility guarantees. I would just bump the REVISION until I was ready to make a guarantee on API stabiliity, at which point it would become version 1 (or whatever is the next version)

                                  1. 1

                                    I’m not sure if this encourages bumping the revision number until you’re ready to make a guarantee, (or maybe it does and I’ve missed it?)

                                3. 1

                                  Am I understanding correctly how this handles back-ported patches?

                                  Say I have the releases:

                                  1.1
                                  1.2
                                  
                                  2.3
                                  2.4
                                  

                                  But then the change in 2.5 needs to be backported to the “1” API, but because of:

                                  (4) Release number Y (x.Y) MUST be incremented on every release. A release number MUST be incremented by at least 1. The release number SHALL NOT ever be decremented.

                                  I’d have a new version 1.3 and 2.5 ?

                                  That seems a little weird then having 1.1 , 1.2, 1.3, 2.3, 2.4, 2.5

                                  1. 3

                                    I believe you’d have 2.5 and 1.6.

                                    Compatibility number X (X.y) MUST be incremented if a release is not compatible with an existing release. Compatibility is defined by the documented semantics of a an API changing in a way that would break existing uses or portions of the API being removed. The release number SHALL NOT be decremented. For instance, the following sequence of releases: 1.0 -> 1.1 -> 2.2 -> 2.3 -> 1.4 -> 2.5

                                    1. 1

                                      Ah, OK, that makes sense and seems more consistent.