33

Context: I recently found out about Semantic Versioning, and am trying to determine how to best use it practically for my own projects.

Given that semver takes major changes, minor changes, and patches into account for versioning, when should a commit not be tagged with an updated version? It seems to me that every change would fit into one of these categories, and so every change should be versioned, but when I look at various popular projects on GitHub this doesn't seem to be the way things are done (just looking at the fact that large projects have tens of thousands of commits, with only hundreds of tags).

VortixDev
  • 439
  • 4
  • 8
  • 24
    Is _every_ commit to master a stable, tested, quality assured release in your project? – Alex Reinking Mar 04 '19 at 21:06
  • 1
    @AlexReinking Every commit is tested, but I'm just trying to get accustomed to common practices with my personal projects, so it's just me working it and as such there isn't really a system in place other than "make a change, test it myself, commit it". – VortixDev Mar 04 '19 at 21:10
  • Also note that tags can be changed later. The only rock solid commit identifier is the commit hash key. – Thorbjørn Ravn Andersen Mar 05 '19 at 08:30
  • 9
    every commit to master ??? you should never commit to master. Every merge to master sounds a lot better. – xyious Mar 05 '19 at 14:27
  • @AlexReinking I don't think its fair to say only "stable, tested, quality assured release[s]" should ever be a new version number. I have worked places where anything that went into QA had a updated version number. It had downsides, public releases where not always sequential, but it's conceptually simple to all involved and seemed to work quite well. – drjpizzle Mar 05 '19 at 14:45
  • 2
    I think @xyious hits the nail on the head. Every commit that ends up on master should be tagged with a version because every commit on master *should be a release merge from develop*. – BJ Myers Mar 05 '19 at 17:17
  • 1
    @BJMyers although if you fast forward merge, your WIP commits will end up in master unless you squash. Tag on every merge works though. – Baldrickk Mar 27 '19 at 15:21

4 Answers4

74

SemVer concerns versioning releases, not commits. If your version control model happens to require that every commit to master be a release, then yes, every commit will need to be tagged according to the degree of the change.

Generally, though, projects develop a mostly stable product on master and tag the releases they deem worthy of support. When they do so, they will tag according to their versioning scheme, which doesn't necessarily have to be SemVer in particular.

Alex Reinking
  • 1,607
  • 11
  • 16
  • 6
    SemVer mostly only makes sense for libraries where the user is other bits of code and not humans. There aren't really any "breaking" changes in most user facing apps because the user can automatically adapt to the new version. – Qwertie Mar 04 '19 at 23:34
  • 5
    I would argue that command line versions of user facing apps should be semantically versioned since their flags and output formats can behave differently. Bit of a grey area. – Alex Reinking Mar 04 '19 at 23:41
  • 5
    @Qwertie User expectations are less rigid than software expectations but they do still exist. I have DEFINITELY used many pieces of software that have issued what I would consider 'breaking' changes to their interface or functionality. Deciding what constitutes a major vs. minor release is certainly more subjective than with libraries, but that's not necessarily a reason to avoid it. – Iron Gremlin Mar 05 '19 at 00:05
  • @IronGremlin Seeing a major version change in a library is a message to a developer that they need to read a change log to see if they use anything that was changed and to do extra testing. What is a user expected to do when they see a major version change? Prepare to write angry emails? – Qwertie Mar 05 '19 at 00:09
  • 11
    @Qwertie - hold back upgrading. How many people still run old major versions of Windows and Office? – Alex Reinking Mar 05 '19 at 00:12
  • 5
    @Qwertie They might be inspired to carefully read the change log or documentation so that they can adapt the way that they use the system to make use of new or modified features, or find workarounds for a feature that's been removed. It's the same case, their use of the software needs to change because the software has changed, so you should tell them about that change unambiguously. – Iron Gremlin Mar 05 '19 at 00:19
  • "There aren't really any "breaking" changes in most user facing apps" is a statement that's very wrong in a lot of cases! File format versions, UI differences, removed features, unwanted features (telemetry), loss of backwards platform compatibility, etc. – pjc50 Mar 05 '19 at 12:42
  • @Qwertie As others have pointed out, but I would like to stress the point, from both the user and the developer point of view, I see no good reason for user facing programs not to be versioned as rigorously as libraries. Its not difficult, its simplifies things by only having one approach, and all the same issues are possible. That a user _may_ be able to compensate is a risky mitigation (I have seen it fail a few times). – ANone Mar 05 '19 at 14:37
  • 3
    If anyone thinks there can't be breaking changes in a UI, can you please support my grandmother next time Facebook does a major change? Thanks... – user3067860 Mar 05 '19 at 15:50
  • @Qwertie, a software application I use makes good use of semantic versioning: a change in major version number denotes a backwards-incompatible change in the file format. For example, version 7.5 can read a version 7.8 data file or a 6.0 data file, but it can't read a version 8.0 file. – Mark Mar 05 '19 at 21:24
  • Your program should be able to migrate formats over to the next version automatically. Also ui changes/unwanted features are not helped by a version number. You can't just continue using old versions of software if you want to continue having a secure computer. Versioning in a library provides a clear path for a developer to move to the next version. For user software they can just try using the new version and if something has moved they can look it up on google/the user guide. – Qwertie Mar 05 '19 at 22:34
  • @Qwertie Sometimes after upgrade you need to quite abruptly downgrade. "Major" signals that you cannot handle newly entered data (or migrated data) in the old version. Let's say you introduced payments in EUR currency, what will you do with the accepted payments if you suddenly need to go back to the USD-only version of the ecommerce software? – kubanczyk Mar 05 '19 at 22:54
12

Version numbers are allocated to releases. In general not every commit should be a release. There are several reasons for this.

Firstly while you say you "test" every commit there are levels of testing. Running an automated testsuite on one machine is all well and good, but in complex software it probablly wont' catch every issue. Some issues may be hardware or configuration specific, some issues may be more about human-subjective considerations than about hard testable requirements.

Secondly bumping the major version number should be a rare action. It basically means that everything that depends on your software needs to be manually checked to see if it depends on any of the removed features.

A consequence of this is you should only add features to your "public API" in full (not alpha/beta) releases if you are prepared to support those features in their present form long-term.

Thirdly it's helpful to keep the number of versions in widespread use down. Even on a stable branch it is often better to gather a number of fixes together and make a single release than to make a release for every fix.

Peter Green
  • 2,125
  • 9
  • 15
3

Seems to obvious to say, but: a version numbers purpose is to let you easily determine what version of the software anyone is running.

If there is any chance of anyone having access to a particular iteration of the code, and not otherwise easily be able to determine a unique identifier, then that iteration should have a unique version number. I see this as the 'first rule'. As a consequence, distinct releases will clearly want distinct version numbers.

However, more comes into play:

One way to be sure of this is to bump version numbers with each commit but this is not usually a good idea. It may take several commits/iterations to get a relatively small change working, and it's confusing to the outside world to see version 0.0.1 -> 0.0.2 as a result of a large number of accumulated changes then 0.0.2 -> 0.0.56 because someone committed white space fixes one file at a time and didn't change anything functional.

How far down the road from "one version per full release" to "one version for each commit" is really up to: you, the other users, and what systems you're willing to use to fill the gaps.

I personally am used to working on small projects, and am happy to use git hashes until a version that others use and a bump version for each of these (no matter how few people I am expecting to get their hands on it). However in larger companies and larger projects something outside semantic version numbers, but lower fidelity than each commit, like release candidate numbering is used. These have advantages but add complexity.

ANone
  • 311
  • 2
  • 5
  • "One way to be sure of this is to bump version numbers with each commit but this is not usually a good idea. It may take several commits/iterations to get a relatively small change working, and it's confusing to the outside world to see version 0.0.1 -> 0.0.2 as a result of a large number of accumulated changes then 0.0.2 -> 0.0.56 because..." - I can't wrap my head around this. You say bumping version with each commit is not a good idea but then you state that it is confusing to have 0.0.1->0.0.2 for a large number of commits. Could you clarify that paragraph? – Rev Jul 06 '23 at 12:33
0

Every pull request that gets merged to master should be versioned.

If it shouldn't be a new version (at least a patch), it likely shouldn't be merged to master because the feature/fix/etc is not complete.

However, depending on your team's workflow you still might end up with multiple commits to master without a version. If there are several commits in a pull request that do not get squashed (They shouldn't in my opinion), you may still end up with 10 commits and just 1 new version.

hba23
  • 19
  • 3
xyious
  • 241
  • 1
  • 5