Maintaining Open Source Projects: Versioning and Releasing

Have you ever wondered when to release a new version of your software? How often should you issue a release? What version number should it be, and why? When will version 1.0 be ready?

And that’s taking into account only what version number to use and when to release it. More questions might arise regarding compatibility: when is it time to release breaking changes? If a vulnerability was fixed, how should you release and announce it? Should you keep maintaining multiple versions of your project? When and how should you deprecate APIs?

Semantic Versioning

Semantic Versioning (SemVer) is a specification that defines rules for changing software version numbers. These rules are intended to minimize the pitfalls of version lock (the inability to upgrade a package without having to release new versions of dependent packages) and promiscuity (allowing dependency versions that are incompatible). Under this scheme, version numbers and the way they change convey meaning about the underlying code and what was modified from one version to the next.

Semantic Versioning uses a three-part number, MAJOR.MINOR.PATCH. Each of the parts is incremented according to:

  • MAJOR, when a change is API-incompatible with previous releases
  • MINOR, when new functionality is added in a backwards-compatible manner
  • PATCH, when bug fixes are made in a backward-compatible manner

SemVer provides a shared language for library authors and users to speak about the kind of changes that new releases contain.

Not a silver bullet

Jeremy Ashkenas, author and maintainer of CoffeeScript and backbone.js among others, states that SemVer is an oversimplification of an inherently human problem:

If your package has a minor change in behavior that will “break” for 1% of your users, is that a breaking change? Does that change if the number of affected users is 10%? or 20? How about if instead, it’s only a small number of users that will have to change their code, but the change for them will be difficult? — a common event with deprecated unpopular features.

Ultimately, SemVer is a false promise that appeals to many developers — the promise of pain-free, don’t-have-to-think-about-it, updates to dependencies. But it simply isn’t true.

Still, SemVer makes library maintainers think twice before breaking their APIs, simplifying the upgrade process in most cases.

Other reasons to bump versions

Releasing new versions can also be a powerful marketing move. Who doesn’t like an announcement at Christmas or at an annual conference that your favorite library now has a bunch of shiny new features? “Have you heard of version 5? They just announced it! Grab it while it’s hot!”

There can also be branding or political meaning in version changes.

Time-based releases

With time-based releases you create early and frequent releases, creating a tight feedback loop between developers and testers or users.

Pick a reasonable time frame for your project, so that you have a good balance between releasing very often (for instance, each time you merge a pull request) and very seldom (for instance, once a year). If you release too often you might annoy people when they upgrade; if you wait too long to release, fixed bugs won’t reach the majority of your users.

Security fixes or bugs that block most people from using the project should be released as soon as possible, regardless of schedule.

On the other hand, sometimes there might be no changes to publish, and when a period finishes there is no need to release.

Maintaining Open Source Projects

This post is an excerpt from the chapter on versioning in our book, Maintaining Open Source Projects. If you’d like to learn more about how we do open source at thoughtbot you can download a free sample, and you may buy the latest version at a beta discount. Enjoy!