Let's say my npm package of 1.0.0 publicly exposes a function called foo for users to use among many other functions and features.
I then remove the foo function which will break for all the users who are using this function.
NPM says:
Changes which break backwards compatibility: Major release, increment the first number, e.g. 2.0.0
I'm quite confused exactly what this means.
Should the major number be updated always if we break a change for users even if it's just a small change such as removing a function?
At the moment I update the major number whenever I possibly break a publicly exposed feature. I see npm packages with small major versions and thinking that I am incorrect in doing this as I am updating my own packages major number very fast.
Each API change (e.g. removing endpoint, function from lib, or changing behavior of endpoint/function) which may impact clients should update MAJOR number. MINOR and PATCH tells client that library/API is stable for one MAJOR version.
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.
You can read more at http://semver.org/
Related
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.
I have a concern about updates related to package.json (dialogflow). I would like to know when I need to update the dependencies. For example I have "actions-on-google": "^ 2.2.0" and check a new version "3.0.0" or "nodemailer": "6.4.11" with the new version "6.7.0". I would like to clarify that with all previous versions the dialogflow agent actually works fine. However in the future it may not work without updates ...
Can anyone give me a suggestion?
Thanks
Applications depends on a variety of third-party packages. As time passes, dependencies on the application will change.
There are two things you need to know about the dependencies updates.
When and why do you need to update application's dependencies.
Some reasons you need to update the dependencies:
Security and Critical bug fixes. Security updates and other critical bug fixes need to happen as soon as possible. Application needs to be secured enough for someone not to steal your data or your data being corrupted.
New releases with new features. Updates have new APIs, and less critical but still a useful bug fixes.
For best practice, you should atleast update the dependencies once or twice a month. Most of the dependencies won’t have an update, or will only have point releases, this makes the update low risk. When doing updates frequently, there's only a small number of major changes should have happened, so if there are problems you will be able to easily pinpoint the issue.
The Symbols relating to the package version.
Version number is split into three values. These are called major, minor and patch. For example, "nodemailer": "6.4.11", the major is 6, the minor is 4 and the patch is 11. The patch will change most frequently (for very small change), while the major should only be changed if there are a major or serious code overhaul.
Symbols:
equality. If not operator in front of the version number or having equal sign in front. Example, "nodemailer": "6.4.11" or "nodemailer": "=6.4.11"
less than/greater. You will see <=, >, etc. Example, "nodemailer": ">=6.4.11" would match 6.7.0, 6.6.5, 6.5.0, etc.
hyphen. You can use - between two versions, the you specify. This is useful if you need to maintain some legacy feature that you know will break at a specific version. Example, 6.4.11 - 6.6.5. This will include both endpoints.
X marks the spot. Any of X, x, or * may be used to “stand in” for one of the numeric values. Example:
* := >=0.0.0 (Any version satisfies)
6.x := >=6.0.0 <7.0.0 (Matching major version)
6.4.x := >=6.4.0 <6.5.0 (Matching major and minor versions)
tilde. The ~ means "approximate version". This allows for more recent patches, but does not accept any packages with a different minor version. Example, ~6.4.11 will allow values between 6.4.11 and 6.5, not including 6.5.
carat. The ^ means "compatible with version", and is more broad than the tilde. It only refuses changes to the major version. Example, ^6.4.11 will allow any version between the value and 7.0.0, not including version 7.
For more information, please check 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 😉
Common practice for version numbers of npm dependencies in package.json has been to enter exact version numbers (like 1.2.4) instead of inexact version numbers (like ^1.2.4 which allows installing bug fix releases like 1.2.5) to make sure a future installation will not break due to changes in dependencies (see for example this article).
Using exact version numbers has a drawback in that you can't automatically update bug fix versions of dependencies. This is an issue when it's nested dependencies having security fixes or bug fixes. For example, at this moment the package karma-browserstack-launcher uses browserstack, which is using an outdated version of https-proxy-agent containing a security vulnerability. This becomes very visible right now thanks to npm audit which looks for security issues in dependencies.
Since some time we have package-lock.json, which is used to lock down the version numbers of all dependencies. This may change the way we deal exact or inexact version numbers in package.json.
My question is: given package.json and package-lock.json, what is the best strategy nowadays to deal with version numbers of dependencies? Use exact versions or not? How can I deal with security issues in nested dependencies if they don't get upgraded?
My feeling is that
packages that are libraries and meant to be used to others should have inexact version numbers and should specify the minimum they require in order to work; and
top-level projects that aren't going to be included elsewhere should specify the full version numbers of their requirements, so they can have the most control over when things are updated.
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.