Cake
  • Log In
  • Sign Up
    • I wonder about version numbers - specifically, what way of versioning apps (or other, mostly user-facing software) is really sensible.

      There are several approaches to this problem in general, one of which is Semantic Versioning (SemVer):

      This versioning scheme strictly doesn't apply to most apps, though, because those don't really have a "public API". One might be tempted to use this scheme anyway, because so much of it makes sense - but then it becomes necessary to define what an app's analogue to a "public API" is, and what exactly constitutes a "backwards incompatible change" to it.

      In the past, I tried to mimic versioning schemes I saw elsewhere, but those are really all over the place as well. Take Google, for example: big company with all sorts of app, if anyone has a clue what might work and what doesn't, it's probably them. However, when I checked version numbers of Google apps installed on my phone right now, I found at least fifteen(!) different versioning schemes and stopped counting at that point. Here's an annotated list:

      One number:
      2018090624

      Having one number is the most simple approach. In this case, the number could be the date (September 6, 2018) of finalizing this app version, perhaps combined with a counter (24th release?).

      Two numbers:
      3.3

      MAJOR.MINOR is often seen in version numbers. For this versioning scheme to be sensible, it needs to be defined what exactly constitutes a "major release" vs. a "minor release".

      Three numbers:
      10.11.2

      MAJOR.MINOR.PATCH is another scheme used often, and also suggested by Semantic Versioning. As mentioned above, it is unclear how exactly SemVer applies to apps that don't come with any "public API", so this needs to be interpreted differently.

      Four or five numbers:
      2.9.40.16
      72.0.3626.121
      5.9.0.19021516
      2.09.11-130
      1.19.092.02.35

      If more than three numbers are necessary for a version number, the fourth and fifth numbers are sometimes called BUILD or REVISION. In the above cases, the individual numbers must have different meanings - for example, the second version number has a 4-digit number in its third position (build number?), whereas the third one ends in an 8-digit number (release date again?). There's also some potentially meaningful variation in separator (dot vs. dash) and in whether numbers have a fixed length or not (some start with a leading zero).

      More than just numbers:
      7.5 (213680574)
      2.5.052 (2005148-30)
      8.19.7938-1.M
      9.2.3.235065705.release
      6.0.22-234118388-release
      8.0.4.236324529-release-armeabi-v7a
      49.0.236391473.DR49_RC05

      Last but not least, there's a whole range of version numbers that include additional information in the form of strings or parenthesis:

      - "release" or "RC##" ("release candidate") is sometimes used to identify app versions that are meant for the public (vs. "alpha", "beta", "canary", ... for internal testing)
      - "DR49" seems to be a repeat of the first number ("Duo Release 49"?).
      - "armeabi-v7a" is a reference to specific hardware that is supported by this app version
      - several of the version numbers use a 9-digit number in a similar range (213... - 236...). I assume that this might either a date/time representation standardized across Google, or something like a reference for the most recent commit to Google's monolithic code repository (link below).

      <END OF LIST>

      The conclusion to draw here is that it either makes sense to have more than a dozen numbering schemes going on at the same time - probably depending on what exactly an app does and needs - or that Google's developers are just as clueless as the rest of us when it comes to versioning.

      Something worth noting here is that all of these versioning schemes and their resulting version strings are not necessary for your phone to work, or your app store to update your apps properly. This is because all of these version strings are considered to be just "names" by the app store. They are shown to users, but are never used to decide whether the app installation on your phone needs to be updated. Instead, there's a separate variable called a "version code" that is used for this purpose. The version code is a single integer number that monotonically increases over time - and if the version code of your app installation is smaller than that of a compatible version available via the app store, the app gets updated on your device.

      This leaves two main functions that a version number should fulfill. It should be sensible to end users that see it, and informative to developers that receive bug reports with that number. The only requirement for the latter is that version numbers are unique (and perhaps that misspelling one doesn't lead to a valid other).

      What sensible versioning schemes do you use, or can you think of - and why?

    • For most of the code I release, I prefer Semantic Versioning. It's made my life much simpler both as an author and as a consumer of software libraries.

      I agree that it's less clear how to apply Semantic Versioning to a user-facing app. I think it can still be useful though, if you think of users' interactions with your app as its "public API".

      Behind-the-scenes changes or minor UI tweaks might only warrant a minor or patch version bump, but a major UI overhaul or the introduction of significant new features could be considered a change to how most users will interact with your app, and thus a change to its "public API".

      That said, I think there's also a strong argument to be made for date-based versioning for user-facing software. It's easy to understand and doesn't require any hand-wringing about whether a change is "big enough" to warrant a major version bump.

    • I agree that Semantic Versioning is a great tool when dealing with software libraries. Whenever a new version of a library I use becomes available, I need to decide whether changing to that version is necessary - or perhaps even important. Similarly, when I'm releasing such libraries myself, I want my consumers to be able to properly make these decisions.

      This doesn't really apply to user-facing software, especially in contexts where users don't have to decide if they really need the update: app updates are typically free, and the cost of downloading updates over a Wi-Fi connection negligible. The fact that updates are also mostly automated means that most users don't even need a publicly visible version. One might even argue that displaying a version number is unnecessarily revealing implementation details that the user doesn't need to be aware of.

      Thinking about the differences between "library software" and "end-user software" some more, my conclusion is that I was probably thinking about this the wrong way:

      With library software, it is a good idea to release often, and then make sure that the version number matches the changes since last release. With end-user software, it should work the other way around. Assign version numbers according to the extent of changes - but only then decide if the new version should be released. In this case, having something similar to SemVer can help with that decision.

      An example:

      First released version of an app gets version number 1.0.0. From there, branch out to two separate code bases:

      - Release, to fix bugs in released app; this will only ever increase the third position (1.0.1, 1.0.2, ...) and should not include new functionality.

      - Development, to work on new functionality; first version after release should increase the first position (2.0.0), subsequent development versions should increase the second position (2.1.0, 2.2.0, ...). Some of these might be made available as Alpha or Beta, but without receiving separate bug fix treatment. If new functionality is ready for release, repeat the process.

      This ensures that there are only ever two code branches to maintain, while at the same time codifying the circumstances that should lead to a new release.

      If this is followed through, it means that end users will only ever see one combination of MAJOR and MINOR. For example, if version 3.11.0 gets released, it means that they haven't seen 3.10.x, and that there won't be a 3.12.x. If that's the case, we're back to the "unnecessary information" part. Does it make sense to replace this with something more readable (code names, perhaps?) - or is actually no one ever looking at version numbers, anyway? :D