How to introduce incompatible changes while remaining in major version zero? - semantic-versioning

I have a large personal software library that I have been working on and is currently working on. Currently, its version is 0.1.0.
It is not mature enough to have a major version of 1. I keep modifying the code and introducing incompatible changes that would merit an increase of the major version number. At the same time, some of my other libraries depend on this library and refer to it by the version number.
If I introduce incompatible changes and don't want to increase the major version from 0 to 1, how should I increment my version number?
The SemVer website is not very clear on that, it just says:
Major version zero (0.y.z) is for initial development. Anything may
change at any time. The public API should not be considered stable.
Does "anything may change at any time mean" that an exception is made for a major version of 0 and that I can change the y and z numbers however I like?
For instance, if my version is 0.1.0 and I introduce an incompatible change, could the new version with that change be 0.2.0?
What others say
On this site it says:
In fact, the SemVer spec defines that anything starting with β€œ0.”
doesn’t have to apply any of the SemVer rules.
Another site also seems to suggest that it is OK to increase the minor version when the major version is 0 and incompatible changes are added:
So you just continue through the 0.x.y range, incrementing y for every
backwards-compatible change, and x for every incompatible change.

It's up to you because
If other libraries depend on your software it means that your software has some consumed public APIs and if it has them... Why isn't already at 1.x.x version?
After all... why is so important that your software reaches the 1.0.0 version only once it's stable? It could start with 3.0.0 or 4.0.0 once it reaches a stable version...
Your software isn't mentally decoupled from your bigger project because, in fact, you'll consider it "mature" only when the whole software (made of a lot of smaller libraries) reaches a "mature" version. But from a technical perspective it's already decoupled πŸ˜‰
It's right that starting from 0 you don't have to strictly adhere with the semver rules
Everything revolves around what is considered "mature". You told that your software isn't mature but what does it mean? That could be improved? That it doesn't cover all the corner cases? That it's not 100% tested?
In the end: if you don't consider it mature continue with the 0.x.y versioning and increase the minor version but your immature software is already consumed by other libraries so it should now reach the 2.0.0 version πŸ˜‰

Related

How to increment the version of package using semantic-versioning, if several bugfixes and a new backward compatible feature have been added?

The semantic versioning system states that a backwards compatible bugfix means that you increment the patch version number (z in x.y.z). It also states that a backwards compatible feature addition should be introduced by incrementing the minor version number (y in x.y.z).
What if both of these things have been added a new release is due? Does one only increment the minor version number?
Semver is a great framework when each addition gets its own release. In this case, you would have ideally released the patch version updates for each bug fix, and then the minor version. However, having collated all those things together, your intuition is right. You can simply bypass the patch versions and bump the minor version. Just make sure to mention the bug fixes in the changelog to help your users know what has happened.
And remember, frameworks are meant to enable you to do things quickly, rather than be strict guidelines. So, nothing out there says that what you're doing goes against semver, it's just adapted to your way of working.

Reason for MINOR vs PATCH rules in SemVer

The rules for when to increase the MAJOR vs the MINOR version number with SemVer 2.0 are very compelling. They clearly give a lot of advantages to knowing if the app/service is backwards compatible.
But the site does not really give an reason for the differences between a MINOR and what it calls a PATCH. I don't see it giving the same benefits of MAJOR vs MINOR.
For reference here are the SemVer rules:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
So the only difference between MINOR and PATCH is features vs bug fixes. My company wants to do that differently.
They want to have MINOR be a collection of [backwards compatible] features. "PATCH" (which we call Incremental) be the releases needed to get those features out. (We release bug fixes as we release features.)
For example, if we plan for 7 [backwards compatible] features in our 2.4 release then 2.4.0 may have 2 of the features, 2.4.1 would have 3 more features and 2.4.2 would have the last 2 (perhaps with a bug fix or two in each release).
I can see that this violates SemVer, but I need to know why SemVer has decided to be prescriptive on the differences between the MINOR and PATCH versions so I can know which way to push my company.
NOTE: I hope that this is not too subjective for Stack Overflow. I don't usually ask questions like this, so it is possible that this question will need to be closed...
The standard is deliberately terse. There's nothing in it that prevents you from releasing a bunch of bug fixes along with your new features and you only have to bump the minor field when you do this. If the changes only involve bug fixes, refactoring or documentation that does not add, remove or modify any interface, then you only bump the patch. The whole point is to communicate to your consumers, their level of risk when taking an update from you.
EDIT:
It is a best practice to separate bug fixes (patches) from feature work (minor) and breaking changes (major), into separate releases. This allows your consumers to automatically pick up the latest fixes, without having to deal with feature bloat or breaking changes.
For example, if we plan for 7 [backwards compatible] features in our 2.4 release then 2.4.0 may have 2 of the features, 2.4.1 would have 3 more features and 2.4.2 would have the last 2 (perhaps with a bug fix or two in each release).
Nothing stops you following SemVer convention and release 2.4.0 with 2 features, 2.5.0 with 3 more features and 2.6.0 with last 2 features and a few bug fixes for previously released features.
It is better to follow some common convention instead of reinventing the wheel. You save time thinking, discussing and documenting a custom solution as well as avoid confusion within the team and newcomers.
https://semver.org/

When using semver when to upgrade/bump to 1.0.0 (stable)

The Semantic Versioning Specification (SemVer) defines:
Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.
So starting with 1.0.0 is considered stable.
When starting a project normally version 0.1.0 is used and gradually increased, there is a point where the project can have something like 0.20.3 for months/years and it is "stable".
Therefore would like to know what could be considered good practices to follow besides the criteria, arguments before bumping a project to server 1.0.0.
How you are dealing with this?
If there are not issues/code activity in 3 months the version is dumped?
The development team decides when they have version 1.0.0. It is possible for a project to remain in experimental/prototype mode for very long periods of time. The only thing that matters here is whether the interface and implementation can be considered complete or not. What are your goals? Do you have all the planned v1 features in place? Do you have doubts w.r.t. implementation conformance to the documented interface?
Some teams don't have workflows that map onto the full semver spec, but they use packaging/release tooling that requires a semver version string. In order to be legal, they never release version 1.0.0, so any version bumps literally don't have full SemVer semantics. See #4 in the spec.
When I see SomeLib.0.20.3.pkg I assume it is not stable. A breaking change can occur on the very next minor field bump, whether or not there have ever been any such changes in the past. SemVer is a contract that allows the SomeLib developers to break things without notice in this particular case.
There is nothing in the spec that precludes a team from issuing a 1.0.0 and then returning to a long sequence of 0.x.x releases if they so desire to operate that way. This is similar to, but not exactly the same as using prerelease tags. When you issue 1.0.1-prerelease you are at least implying intent to release a work derived from 1.0.0 that is a bug-fix, but the prerelease tag is warning label that you are not yet certain of the safety of the changes you made. Following on from 1.0.0 to a sequence of 0.x.x releases says you might not even be deriving from 1.0.0 anymore. Basically, all bets are off again.
If you require any further elucidation on this matter, please ask, I am happy to try to answer any questions regarding SemVer.

Why is node.js v4.4.5 recommended over v6.2.0 "for most users"?

I used node.js for a development project a few years ago, and this app is somewhat "mothballed" for the time being β€” it needs to stay online, it needs to stay secure, but it shouldn't need much attention. It is currently running on node.js v0.10.32, but I would now like invest in a "final" migration to a Long Term Support (LTS) release so it will be easier to maintain for the foreseeable future.
At first glance, the node.js homepage makes it look like v4.4.5 is obviously the only available LTS release:
However if I click that LTS schedule link, it tells a different story. As far as I can tell, version 6 of node.js is also slated to be an LTS release, with that support ending a full year later than version 4 will be.
Given that:
v6.2.0 is a versioned release
v6 is purported to receive LTS maintenance until 2019-04-01
theoretically no changes in v6.x should break backwards compatibility
Why would I bother upgrading to v4 instead of v6? Seems like v4 buys me one less year of security patches, but no additional compatibility guarantees?
With gratitude to jasnell and TheAlphaNerd who patiently answered my acerbic questions over on GitHub, here's my understanding of how node.js "long term support" releases are handled:
All releases based on an even-numbered major branch are what other projects might call a "long term support" version. They are promised at least 30 months of support from the first "cut" made available (e.g. a packaged v6.0.0 releases).
However, the node.js maintainers see "LTS" as more of a release phase than a version type. While they intend for minor/patch releases made when a major branch is in its active improvement (see "CURRENT" below) phase to be stable and backwards compatible, in the real world they might make mistakes.
So they divide development into three distinct phases:
CURRENT: new features (and bug fixes and security patches)
ACTIVE LTS: bug fixes (and security patches)
MAINTENANCE: only security patches
Odd-numbered major versions get only the first phase before being left behind. Even-numbered major versions β€” the ones we're mostly concerned about here β€” go through all three phases.
The CURRENT phase starts with the first public release, and starts the clock ticking on the 30-month support window. They may add significant new features, which should in theory be backwards-compatible but in practice may turn up some issues (new bug gets added, change made to poorly-defined behavior, they fix an old bug you had worked around poorly, etc.)
Then at some point the team decides to move the main development effort to a short-lived odd-numbered major branch (presumably when they need to intentionally break backwards compatibility). At that point the even-numbered branch moves to ACTIVE LTS and they get much more careful with the changes they make: primarily just bug fixes. So if you really want stability, this is the time to get "on board" with a particular release.
Eventually it moves even further to the MAINTENANCE phase, where the code is touched only in response to the most critical bugs (think: security patches). But by then there's probably a new release in LTS "phase" already.
So the choice on the homepage right now is between two even-numbered branches, "v4.4.5 LTS" and "v6.2.0 current". If the newer branch were odd-numbered then it would not be a good candidate for a production deploy where long-term support is desired.
My actual options are a bit more complex even:
I could simply stay on v0.10 which will get critical fixes until October. Or bump up to v0.12 to get those until the end of the year. But neither one of those gains me much, and so I'll rule them out.
I can deploy v4.4.5 which will is still getting general bug fixes right now, and will get security fixes for quite a while yet. This should give me the most stable install. The support cycle is getting to be halfway over already, though β€” and when it runs out I'll have missed this opportunity now to catch up with some of the major changes that have already happened in v5 and v6.
I am leaning towards deploying v6.2.0, assuming all my dependencies support it right now. This not only buys me a year longer term of "lifecyle remaining", but also gets me fully caught up with any breaking changes that were introduced between v0.10 and now. (It also gets me access to any useful new features β€” but in this case I don't have a chance to take advantage of it.) The risk I take is that when I update to any hypothetical v6.2.1 or v6.3.0 or beyond that comes along, it might accidentally yield some bad surprises.
In my case I'd rather deal now with the major intentional changes that v5 and v6 have already introduced, and then hopefully be all set (or at least only minor pain) from now all the way until April 2019.

Getting software version numbers right. v1.0.0.1 [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I distribute software online, and always wonder if there is a proper way to better define version numbers.
Let's assume A.B.C.D in the answers. When do you increase each of the components?
Do you use any other version number tricks such as D mod 2 == 1 means it is an in house release only?
Do you have beta releases with their own version numbers, or do you have beta releases per version number?
I'm starting to like the Year.Release[.Build] convention that some apps (e.g. Perforce) use. Basically it just says the year in which you release, and the sequence within that year. So 2008.1 would be the first version, and if you released another a months or three later, it would go to 2008.2.
The advantage of this scheme is there is no implied "magnitude" of release, where you get into arguments about whether a feature is major enough to warrant a major version increment or not.
An optional extra is to tag on the build number, but that tends to be for internal purposes only (e.g. added to the EXE/DLL so you can inspect the file and ensure the right build is there).
In my opinion, almost any release number scheme can be made to work more or less sanely. The system I work on uses version numbers such as 11.50.UC3, where the U indicates 32-bit Unix, and the C3 is a minor revision (fix pack) number; other letters are used for other platform types. (I'd not recommend this scheme, but it works.)
There are a few golden rules which have not so far been stated, but which are implicit in what people have discussed.
Do not release the same version twice - once version 1.0.0 is released to anyone, it can never be re-released.
Release numbers should increase monotonically. That is, the code in version 1.0.1 or 1.1.0 or 2.0.0 should always be later than version 1.0.0, 1.0.9, or 1.4.3 (respectively).
Now, in practice, people do have to release fixes for older versions while newer versions are available -- see GCC, for example:
GCC 3.4.6 was released after 4.0.0, 4.1.0 (and AFAICR 4.2.0), but it continues the functionality of GCC 3.4.x rather than adding the extra features added to GCC 4.x.
So, you have to build your version numbering scheme carefully.
One other point which I firmly believe in:
The release version number is unrelated to the CM (VCS) system version numbering, except for trivial programs. Any serious piece of software with more than one main source file will have a version number unrelated to the version of any single file.
With SVN, you could use the SVN version number - but probably wouldn't as it changes too unpredictably.
For the stuff I work with, the version number is a purely political decision.
Incidentally, I know of software that went through releases from version 1.00 through 9.53, but that then changed to 2.80. That was a gross mistake - dictated by marketing. Granted, version 4.x of the software is/was obsolete, so it didn't immediately make for confusion, but version 5.x of the software is still in use and sold, and the revisions have already reached 3.50. I'm very worried about what my code that has to work with both the 5.x (old style) and 5.x (new style) is going to do when the inevitable conflict occurs. I guess I have to hope that they will dilly-dally on changing to 5.x until the old 5.x really is dead -- but I'm not optimistic. I also use an artificial version number, such as 9.60, to represent the 3.50 code, so that I can do sane if VERSION > 900 testing, rather than having to do: if (VERSION >= 900 || (VERSION >= 280 && VERSION < 400), where I represent version 9.00 by 900. And then there's the significant change introduced in version 3.00.xC3 -- my scheme fails to detect changes at the minor release level...grumble...grumble...
NB: Eric Raymond provides Software Release Practice HOWTO including the (linked) section on naming (numbering) releases.
I usually use D as a build counter (automatic increment by compiler)
I increment C every time a build is released to "public" (not every build is released)
A and B are used as major/minor version number and changed manually.
I think there are two ways to answer this question, and they are not entirely complimentary.
Technical: Increment versions based on technical tasks. Example: D is build number, C is Iteration, B is a minor release, A is a major release. Defining minor and major releases is really subjective, but could be related things like changes to underlying architecture.
Marketing: Increment versions based on how many "new" or "useful" features are being provided to your customers. You may also tie the version numbers to an update policy...Changes to A require the user to purchase an upgrade license, whereas other changes do not.
The bottom line, I think, is finding a model that works for you and your customers. I've seen some cases where even versions are public releases, and odd versions are considered beta, or dev releases. I've seen some products which ignore C and D all together.
Then there is the example from Micrsoft, where the only rational explanation to the version numbers for the .Net Framework is that Marketing was involved.
Our policy:
A - Significant (> 25%) changes or
additions in functionality or
interface.
B - small changes or
additions in functionality or
interface.
C - minor changes that
break the interface.
D - fixes to a
build that do not change the
interface.
People tend to want to make this much harder than it really needs to be. If your product has only a single long-lived branch, just name successive versions by their build number. If you've got some kind of "minor bug fixes are free, but you have to pay for major new versions", then use 1.0, 1.1 ... 1.n, 2.0, 2.1... etc.
If you can't immediately figure out what the A,B,C, and D in your example are, then you obviously don't need them.
The only use I have ever made of the version number was so that a customer could tell me they're using version 2.5.1.0 or whatever.
My only rule is designed to minimize mistakes in reporting that number: all four numbers have to be 1 digit only.
1.1.2.3
is ok, but
1.0.1.23
is not. Customers are likely to report both numbers (verbally, at least) as "one-one-two-three".
Auto-incrementing build numbers often results in version numbers like
1.0.1.12537
which doesn't really help, either.
A good and non-technical scheme just uses the build date in this format:
YYYY.MM.DD.BuildNumber
Where BuildNumber is either a continuous number (changelist) or just starts over at 1 each day.
Examples: 2008.03.24.1 or 2008.03.24.14503
This is mainly for internal releases, public releases would see the version printed as 2008.03 if you don't release more often than once a month. Maintenance releases get flagged as 2008.03a 2008.03b and so on. They should rarely go past "c" but if it does it's a good indicator you need better QA and/or testing procedures.
Version fields that are commonly seen by the user should be printed in a friendly "March 2008" format, reserve the more technical info in the About dialog or log files.
Biggest disadvantage: just compiling the same code on another day might change the version number. But you can avoid this by using the version control changelist as last number and checking against that to determine if the date needs to be changed as well.
In the github world, it has become popular to follow Tom Preston-Werner's "semver" spec for version numbers.
From http://semver.org/ :
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes, MINOR version
when you add functionality in a backwards-compatible manner, and PATCH
version when you make backwards-compatible bug fixes. Additional
labels for pre-release and build metadata are available as extensions
to the MAJOR.MINOR.PATCH format.
I use V.R.M e.g. 2.5.1
V (version) changes are a major rewrite
R (revision) changes are significant new features or bug fixes
M (modification) changes are minor bux fixes (typos, etc)
I sometimes use an SVN commit number on the end too.
Its all really subjective at the end of the day and simply up to yourself/your team.
Just take a look at all the answers already - all very different.
Personally I use Major.Minor.*.* - Where Visual Studio fills in the revison/build number automatically. This is used where I work too.
I like Year.Month.Day. So, v2009.6.8 would be the "version" of this post. It is impossible to duplicate (reasonably) and it very clear when something is a newer release. You could also drop the decimals and make it v20090608.
In the case of a library, the version number tells you about the level of compatibility between two releases, and thus how difficult an upgrade will be.
A bug fix release needs to preserve binary, source, and serialization compatibility.
Minor releases mean different things to different projects, but usually they don't need to preserve source compatibility.
Major version numbers can break all three forms.
I wrote more about the rationale here.
For in-house development, we use the following format.
[Program #] . [Year] . [Month] . [Release # of this app within the month]
For example, if I'm releasing application # 15 today, and it's the third update this month, then my version # will be
15.2008.9.3
It's totally non-standard, but it is useful for us.
For the past six major versions, we've used M.0.m.b where M is the major version, m is the minor version, and b is the build number. So released versions included 6.0.2, 7.0.1, ..., up to 11.0.0. Don't ask why the second number is always 0; I've asked a number of times and nobody really knows. We haven't had a non-zero there since 5.5 was released in 1996.

Resources