Product versioning is a common and convenient practice, where product iterations have version numbers assigned to them at each release. This practice then clearly differentiates products from each other moving forward. But there’s more to versioning than just assigning each release the next available number. For example, there’s Semantic Versioning.
What is Semantic Versioning though? To understand it, it’s important to know about the main goal of Semantic Versioning – that is, to give version numbers a specific meaning. Read on to find out more in the next few sections.
Next: what are the benefits of setting it up? Here’s two big ones:
- Transparency – knowing what can be found in each product release, and that
- Predictability – the version number helps developers know what kind of work is involved in updating a dependency to a newer version.
But there’s more to it than that, and the details can be nuanced. This is even clearer when you’re looking back over Tiny’s product evolution, and the decision taken to reevaluate our software versioning best practices as part of Tiny’s continuous improvement.
Adopting software versioning standards with Semantic Versioning
At Tiny, we’ve long been proponents of product versioning. However, we hadn’t been particularly strict about what those versions meant.
That all changed when we made the decision to adopt a strict Semantic Versioning specification. From then on, we added meaning behind each TinyMCE release. To understand the exact benefits gained, let’s first explain what a Semantic Versioning specification actually is.
What is Semantic Versioning
Many developers are familiar with what’s often called “dependency hell”. In particular, a problem developers can hit is when a dependency updates in a way that isn’t backward-compatible. The result? It breaks their project. Depending on how reliant the project is on the changed features, and how big the change is, this kind of problem can be either a quick fix or a massive headache.
Semantic Versioning gives version numbers a specific meaning, so that developers can predict what impact a dependency update carries. This action is now recognized as significant to software versioning best practice.
Semantic Versioning does two things to help this effort:
- Define a format for version numbers
- Set rules around how version numbers are incremented, depending on what was changed in a release
What is a version number in Semantic Versioning?
A version number represents a change in software, with each increment in the version number signifying what has changed compared to the previous version.
Each number is separated by a “.”, and the numbers represent the impact of the change for the product. It follows a format that is essentially MAJOR.MINOR.PATCH. The first number is a major change, the middle number only a minor change, and the final number is a small patch.
It makes more sense when you take a step back and have examples to look at, which show how adopting it helps software versioning best practice.
Major, minor, patch rules
The MAJOR.MINOR.PATCH. format means that the first release of a product is given the version 1.0.0. Each update after that increments the relevant numbers depending on what kind of release it is. The kinds of releases are:
- Patch: Backward-compatible bug fixes (e.g., 1.0.1)
- Minor: Backward-compatible new features (e.g., 1.1.0)
- Major: Any kind of changes that are not backward-compatible, and can include breaking changes (e.g., 2.0.0)
You may have noticed that this not only specifies numbers for backward compatible and incompatible changes, but also differentiates between bug fixes and new features. The idea is that backward-compatible bug fixes, in a dependency, should require the least effort for developers to integrate, if any.
If developers want to use new backward-compatible features, they might need to do some setup or integration, but minor releases should not require work to use out-of-the-box. In comparison, any kind of breaking changes, no matter whether it is a bug fix or a new feature, could require a large amount of work for integrating developers.
✏️NOTE: If you would like to learn more about Semantic Versioning, we recommend reading the official specification.
Some package managers also allow developers to pin a dependency to a “range” of versions. This allows the dependency to automatically upgrade within that range. Combined with Semantic Versioning, if developers pin dependencies to patch or minor ranges, their project can update without the risk of introducing breaking changes. For example, if you use NPM as the package manager for a project, you can pin dependencies using NPM’s version range syntax.
How Semantic Versioning of TinyMCE helps you
When Tiny had product versioning, it wasn’t always descriptive. For example, TinyMCE 5.0.14, was only a patch release, but it also contained PowerPaste 5.1.0.
Despite this being documented in the release notes, it wasn’t obvious from the productversion we used (pre Semantic Versioning) that it also contained a minor version of one of the Premium plugins. This had the potential to cause problems for customers who upgraded TinyMCE without knowing it included changes to PowerPaste.
By adopting Semantic Versioning from the release of TinyMCE 5., TinyMCE releases now adhere to the following versioning rules:
- TinyMCE always follows the rules of Semantic Versioning
- TinyMCE Premium plugins also follow the rules of Semantic Versioning
- Enterprise releases, since they use TinyMCE’s versioning, will only contain Premium plugin releases of the same kind or lesser
The last point is perhaps the most important for Enterprise customers to understand. To explain it in more detail:
- A patch release of Enterprise (e.g., 5.0.1) can only contain patch releases of TinyMCE and any Premium plugins
- A minor release of Enterprise (e.g., 5.1.0) will contain a minor release of TinyMCE and only patch or minor releases of any Premium plugins
- A major release of Enterprise (e.g., 6.0.0) will contain a major release of TinyMCE and patch, minor or major releases of any Premium plugins
Implementing Semantic Versioning in TinyMCE
The other change brought on by implementing Semantic Versioning: release changes.
Releases that only contain bug fixes require less post-development work from the various other teams in Tiny, so they’re able to be released quicker. However, it may slow down major and minor releases for Premium plugins, since they can only go out in major or minor versions of TinyMCE.
While that may slightly decrease the release rate for new features, we believe the increase in stability and predictability for our customers far outweighs it.
Of course, there are always road bumps. At one stage, a major update to one of our Premium plugins unfortunately broke Semantic Versioning rules, as it was prepared before the switch. We minimized the potential impact by pushing it out to a minor TinyMCE release, and by ensuring backward-compatibility. Any exceptions are always well documented in the release notes.
The other great thing about shifting to strict Semantic Versioning, is that it helps our different teams and departments to be on the same page about releases. The Quality Assurance team know what kind of work to expect in each Enterprise release, and can more easily plan their testing accordingly. While Customer Success, Marketing, and Sales teams can know, at a glance, the impact of each release from their perspectives.
The switch has also been part of a larger shift towards better development practices and engineering processes within Tiny. For example, we’ve also implemented Git Flow-like processes within the TinyMCE team, which, incidentally, has made it easier to implement Semantic Versioning.
Software versioning best practices and Tiny
We’re always striving to build excellent things in excellent ways. The adoption of Semantic Versioning creates clear expectations for developers, and reflects our commitment to following best practice for our customers.
Curious about what else we’ve done? Find out about our CDN infrastructure for Tiny Cloud.