Skip to main content

8 Understanding Semantic Versioning

Episode 15 · July 7, 2014

Understand how and why the version numbers work for the gems you commonly use


Transcripts

We're going to talk about semantic versioning and how it affects your Rails applications and the ruby gems that you interact with. Semantic versioning is a standard that was written by Tom Preston Warner from GitHub. He wrote this standard to set a default system for making your version numbers compatible with each other. We see a lot of times Windows XP version numbers from back in the day, they're like crazy, and even ruby itself adds on top of this a little bit, but it adheres to it pretty much, so you might be familiar with seen like ruby 2.0.0.0 -p and a number after that. So they've added a little bit extra into it but they still generally adhere to semantic versioning, and most of the gems that you'll see also do, and Semantic Versioning itself adheres to the standard (unsuprisingly). So what is semantic versioning and why is it important?

What happens is when you're using a gem or depending on a library, when a version number changes, it could cause problems in your application. The way that this is designes is when you see the numbers change, you know generally what level of changes have happened. For example if the last number changes, that is just saying that it has fixed a bug, and that's it. So there's been a bug fix, great! In almost every case, we always want to include the bug fixes, for Rails, if there's a bug fix, it's certainly important because it's probably related to a security problem.

When the middle number of a version changes, this represents that the developer or company has added fuctionality in a backwards compatible manner, and that's important. The backwards compatible part of the last two numbers are very important. That basically means that what we've got will still work with the old version, we've added some new features and we've pathched some bugs. So the last two numbers represent things that are non breaking. So when you're using Rails, for example, Rails 2.3 is going to be a lot different than Rails 3.1 or 3.2 or 4 or 4.2. So when you go from a major version here, there's going to be a significant amount of changes. But going from Rails 4.0 to 4.1, will only change the middle number, and that means that you should be able to upgrade relatively seamlessly and not run into any breaking problems. But if you're going to go from 3 to 4, you're going to have to update a lot of your code to make sure it's compatible. And that's why the first number is the one that is potentially the most dangerous. If you accidentaly update your Rails application from 3 to 4, everything is going to break and you're going to have to go back either to Rails 3 or to go patch your code to be compatible with the latest version.

Semantic Versioning basically gives you an insight into what has changed just by glancing at the numbers. Let's take a look at that in our Gemfile and see how that affects us.

I have an example Gemfile here with only the Rails gem in it, but it's set to a little bit older version (4.0.3), and we want to make our application compatible with all of the security patches that Rails will recieve. So what we have right now is only ever going to install version 4.0.3, there's nothing here that says to take the updates, and if you want, you could change this version manually and handle that. But that's not really the most effective way to handle your Gemfile.

If we go to the Rails gem, we can see what the lates version is. Now Rails has 4.1.0 which has added some features according to semantic versioning, but it's still backwards compatible with what we're using right now. And if we take a look at Rails 4.0, we can see that there's a 4.0.4 that has been released since we generated this Gemfile, because we're on 4.0.3 If we want to make our Gemfile capable of upgrading versions of our gems automatically, then we can take an approach to this by adding a little bit of syntax into our version strings here. So right now, this is effectively saying that we want Rails gem equal to 4.0.3, and you can specify the equal sign in here to say that. You can also say that you want any gems that are greater than or equal to 4.0.3 which will give you the latest Rails gem, which is going to be 4.1.0, so it's not going to upgrade only this last number, it will upgrade all of them. So if Rails 5 comes out, it will install Rails 5. And that could cause breaking changes, so greate than and equal to are generally not good ideas to use when you're putting these in your Gemfile. And in our case, we just want to upgrade 4.0.3 to 4.0.4 so we know that we have the most secure and patched version and we'll never run into any breaking changes. Our code is written and tested to work on 4.0, and right now we're on 4.0.4, and we want to automatically have bundler update this for us, and if we put a ~>, this is going to indicate to Rails that it can update the Rails gem but only if the last number changes, so you almost always want to use the ~> line in your gem versions just to make sure that you're only patching things and not breaking changes. And this applies to all of your gems, so when we depend upon a whole bunch of gems, there is a much greater chance that one of them is going to throw everything off and really throw a wrench into your Gemfile, and you're going to spend a lot of time trying to fix it.

Last but not least, we could run bundle install to install the gems, and the way that we had it before was that 4.0.3 would be installed, and now that we just changed that to ~>, that syntax is going to upgrade the gem, and when we run bundle update, this is going to install a new version of Rails, and it's going to be 4.0.4. As you can see here, rails 4.0.4 was installed, and that is exactly what we want, so when when 4.0.5 comes out, we just run bundle update, we don't have to change our Gemfile, everything is going to be perfectly set up, and anyone else that uses our Rails application will run bundle install from scratch and they will always get the latest version of Rails. The Gemfile is provided by Bundler, and bundle is the command that we use to install those gems that we specified. If you want to learn more about bundler, take a look at bundler.io and browse the site and learn more about how it works. And if you want to learn about what we just talked about, you can click on learn more about gem files, and it will give you a bunch of information, as well as a manual and version specifiers that we talked about today. If you have a need to install beta versions, or RC versions, or even use >=, you can look into this, and make sure that you're specifying it the right way, and this page also has a whole lot of information about it that will go on real deep if you're interested in learning more about it. That is semantic versioning with bundler and Rails.

Transcript written by Miguel

Discussion