37. Semantic Versioning

November 21, 2017

Today we are going to be talking about semantic versioning. When you should do it, when you shouldn’t do it, and what the heck it is? Joining us on this episode is special guest, Kevin Thomas. Kevin is a Software Consultant at Stride Consulting. Semantic Versioning is a more rigorous system where the first number is the big breaking changes, ideally. The second version is when you add new features, and the third one is like small patches, and sometimes there’s a fourth one just for security fixes. There are like a lot of good examples of semantic versioning out there, many of which have big impacts in the community. Stay tuned as we dive into exactly what semantic versioning is, the importance of learning from the mistakes of others, and the keys to staying current with version upgrades. All this and more inside today’s episode. 

Key Points From This Episode:

  • What is semantic versioning, and what are the implications?
  • Real world examples of semantic versioning.
  • Understanding the importance of making the upgrade path as easy as possible.
  • The Ruby example; learning from Pythian’s mistakes.
  • Why deprecation warnings are really crucial for making upgrading easy.
  • Is semantic versioning a necessity for personal projects?
  • Swiss Train Deployments done by Ember and how they use semantic versioning.
  • iPhone, Chrome, Firefox, macOS; what does their semver look like today?
  • How feedback from the community can lead to gentler upgrade paths.
  • Using programs with automatic upgrades for increased security.
  • And much more!

Transcript for Episode 37. Semantic Versioning

[0:00:01.6] DA: Hello and welcome to The Rabbit Hole, the definitive developers podcast in fantabulous Chelsea. Your regular host, Michael Nunez, is in fantabulous Hawaii, so I’ll be filling in.

[0:00:13.8] WJ: Oh, man. I’m so jealous.

[0:00:16.3] DA: I’m your host, Dave Anderson, and the panelist today. We have our producer —

[0:00:20.5] WJ: William Jeffries.

[0:00:21.8] DA: And a very special guest today.

[0:00:23.8] KT: Kevin Thomas.

[0:00:25.6] DA: Today we’re going to be talking about semantic versioning. When you should do it, when you shouldn’t do it, and what the heck it is?

[0:00:35.8] WJ: Always do it.

[0:00:37.8] DA: Except maybe when you don’t have to, but, yeah.

[0:00:40.9] WJ: Yeah, I’m not semvering my side projects. That is a waste of time.

[0:00:45.6] KT: What is semantic versioning? Do a short explanation we could give for someone who has never heard the topic before?

[0:00:53.8] KT: It’s a way to use a small set of integers to determine, let’s say — People talk about web 1.0 versus web 2.0 very loosely. But this is like a more rigorous system where the first number is like the big breaking changes ideally. The second version is like when you add new features. The third one is like small patches, and sometimes there’s a fourth one just for security fixes.

If the third number changes from like 2.0.0 to 2.0.1, you’re not that worried about the changes, but if it changes from 2.0.0 to 2.1.0 you’d be a little worried. If it’s 2.0.0 to 3.0.0, then anything can break, the APS could break and you’d be worried your entire app will fall apart.

[0:01:37.4] DA: They can’t be held accountable.

[0:01:39.4] WJ: There’s more information on this at semver.org.

[0:01:43.9] DA: Yeah, which itself is semantically versioned. It’s currently at semver 2.0.0.

[0:01:50.5] WJ: We’ll have a link to that in the show notes.

[0:01:52.5] DA: Yeah.

[0:01:53.8] KT: We can only imagine what the breaking changes were between semver version 1.0 and semver version 2.0.

[0:01:58.9] DA: Exactly. It had to have been a big deal. I would like to look at the git-diff. They have a git-repo for that.

Yeah, but there are like a lot of good examples of semantic versioning out there in the wild. Like one that comes immediately to mind to me for semantic versioning and the pain that it can bring is the huge breaking changes that were introduced in Python 3.0, from Python 2.7 where —

[0:02:26.4] WJ: Oh, yeah there was like a huge schism in the community over that, right?

[0:02:29.4] DA: Yeah. I think the biggest thing that broke a lot of libraries was changing how strings were handled, bytes and Unicode and all that fun stuff. It was — A lot of right decisions were made, but basically we have two languages that we’re dealing with and slowly kind of trying to fold everybody back in.

[0:02:49.8] KT: Do you think that folding back in is really going to happen in the next year or so as they officially sunset 2.0?

[0:02:57.8] DA: 2020. It’s the new 2012.

[0:03:01.2] WJ: Have people been coming up with upgrade scripts? I feel like that’s the key to getting people to adopt to the new major version is making the upgrade path as easy as possible.

[0:03:11.3] DA: Yeah. Unfortunately, I think they didn’t really think too much about that. They thought about what the important things were that they needed to do, and they decided to do them and they didn’t really think about the human aspects of upgrading software, which kind of led to where we are today.

[0:03:27.2] WJ: There is one right way to do it.

[0:03:30.1] KT: Yeah, I remember reading an article in 2013, so Python had only been out for five years and adoption was like well below 20%. My biggest suspicion for why adoption was really low is because the Python community doesn’t write a lot of tests. If you don’t have a lot of tests, like if you’re going to break everything, how can you know if you’ve fixed that again?

[0:03:50.2] WJ: Maybe this will be an incentive for the Python community to get more into testing.

[0:03:55.0] DA: Yeah, I think so. I think there’s a new generation of people who are coming from other languages and pollinating Python with good ideas. Kevin, I really like the idea or the example that you had told me earlier about Ruby.

[0:04:08.4] KT: Yeah, I felt like Ruby learned from Python’s mistake in a way. This is just a suspicion. No one officially had said this that I know of, but it seemed like most of the breaking changes are going from Ruby 1.x to 2.0. Most of the breaking changes were actually snuck-in in Ruby 1.9. They changed the way that character strings. Like if you index into a string, it became just a sort of string instead of an integer character and they deprecated some old ways that you couldn’t put paths in dictionaries.

2.0 had comparatively few changes, and then for 2.1 they had more changes again, but they were the changes that like people really wanted to revamp the language.

[0:04:48.2] DA: Right. So they held the carrot out in front.

[0:04:51.1] WJ: Yeah, it seemed like the fact that they were not on simver before 2.0 was an advantage that allowed them to make the upgrade to 2.0 less scary. Then a big part of upgrading to 2.0 was adopting semver.

[0:05:08.4] DA: Interesting. So the breaking change was doing semver itself.

[0:05:11.7] WJ: Yeah.

[0:05:14.5] KT: Semver does communicate clearly, but that can still be very scary to the developers and you still need a path to upgrade.

[0:05:21.2] DA: Right. Yeah. I’ve been thinking about it a lot, considering like we’ve been working more in the JavaScript area, at least I’ve been working more in the JavaScript area. Kevin, I think you’ve been working with JavaScript quite a bit over the past couple of years, but there’s a lot of major releases in JavaScript libraries that you have to keep up with.

[0:05:40.2] KT: Yeah, things break and change really fast. We’re about to get on React 16 and once the major versions jump that fast, it’s unclear where the breaking changes are at all. You kind of lose the meaningfulness of semantic versioning over again.

[0:05:52.1] DA: Yeah, although it is helpful when libraries include deprecation warning. Like Rails is really good about this. Just warning you continuously whenever you run your test suite. There’s something that’s deprecated that you’re using or React has been good about that too.

[0:06:07.0] WJ: Deprecation warnings I think are really crucial for making upgrading easy, because things are deprecated beforehand and you have a while to go through and fix all of the problems. It also puts the developers of the library in the mindset of coming up with clear error messages to give people that make it easy to figure out how to fix the problem.

[0:06:31.3] DA: Yeah, I agree. It is nice when there’s a clear explanation of what that means and maybe even like a reference to some change requests that I can go and read about it more.

[0:06:43.8] WJ: Yeah, a lot of the times the deprecation warnings are mostly an explanation of how to upgrade.

[0:06:48.7] KT: Sometimes those warnings are really annoying, but one advantage of being on a big team is going to assign just like one guy to like go up and clean that stuff out.

[0:06:57.1] DA: Yeah.

[0:06:57.9] KT: Get ready for the future.

[0:06:58.8] DA: You’ve just got to be a good Boy Scout. Leave it better than you found it.

[0:07:01.9] KT: Let’s see —

[0:07:03.0] WJ: Deprecation [inaudible 0:07:02.8].

[0:07:03.2] KT: I don’t really think that the semantic versioning is graced necessarily for the open-source community to like keep marching forward library by library, because each one has to be maintained in its own way. As scary as the major version changes can be, the alternative can be even worse.

I remember when a lot of the world switched from underscore.js to lodash.js that kind of had the same goals with slightly different limitation. Like beyond lodash having better performance, like one of the big reasons was the creator of underscore.js, Jeremy Ashkenas, just refuses and make the versioning, but breaking changes into random patch versions and — Maybe not patch versions, but probably like the medium versions. When he was asked about that by the community, like when there was a little bit of uproar, he just shouted them all down. He just want to do it his own way.

[0:07:50.4] DA: Interesting.

[0:07:51.8] KT: That’s not to be strict semantic versioning, but you need something similar in order for the community to like feel like you’re communicating in a clear way.

[0:07:58.5] DA: Right, yeah. It all comes back to like the human factor of like making sure that people can trust you and the service that you’re providing, like be it a library or — We haven’t talked about this very much, but REST API’s also benefited from semantic versioning. Although, that’s like a topic in itself, like how you can do that really well? It’s definitely a lot easier to package up and release a library than —

[0:08:23.4] KT: If it’s truly for public consumption, yeah, I think that’s really helpful.  Do you guys do semantic versioning for your own private projects?

[0:08:31.3] WJ: No. I think, also, if you have an app that no other developer is going to use, it doesn’t really seem super necessary. That’s more of like a package thing, to me.

[0:08:43.4] DA: Yeah. Even for the web app that you’re developing that’s going to save the world, you may not need a semantic version because you’re always just going to be fixing forward. If you need to report on what version of software is breaking in your error log, then you can just use the hash from the Git command.

[0:09:06.9] WJ: Although I think APIs could be an exception to that. If you have a micro-service architecture and there are a bunch of APIs that are servicing your app, then those APIs probably should be under semver.

[0:09:21.0] DA: Yeah, especially if you’re going to have clients out in the wild that you don’t have control over. Like mobile, because there’s no guarantee that that guy who’s running android 2.1 is ever going to upgrade his application or his phone.

[0:09:36.8] WJ: Yeah. If you’re a dedicated team running an API service that another dedicated team has to consume, you essentially have public customers just like a regular library maintainer does, or a SaSS platform what an API does.

[0:09:52.2] KT: Yeah, that’s true. I feel like the mobile app environment is actually really good about semantic versioning overall. I think it’s because it’s so curated by Apple and slightly curated by Google at times.

[0:10:02.5] DA: Right. You have to get your app approved and on their store. I have never done that myself, but I’m sure there are very clear guidelines, especially for Apple on how to that.

[0:10:14.4] KT: But it seems less necessary, because it’s easier for apps just to like keep upgrading for it automatically.

[0:10:20.6] DA: Yeah, that’s true.

[0:10:23.5] WJ: Yeah, the plain old fashion eCommerce website, not going to need semver.

[0:10:30.9] KT: Sometimes when — Things can feel stale, because it’s stuck in an old version. That was the case with Python 2 lasting a decade longer than anyone expected. Also, Angular 1 just felt it — It really felt like a 1.0 using it almost 10 years after it was created.

[0:10:47.3] DA: Right, yeah. Everyone is on React 15 and they’re still using Angular 1, although it’s like it was 1. whatever in the end. It did seem like it was a better stuff for the community, like a better PR move to start releasing a major version twice a year.

[0:11:04.9] KT: Angular 2 did make some good changes, like they did away with some of the 2A data binding and made that simpler, but still there’s a lot of complexity packed into it. So I think it wasn’t as well received as some other modern upgrades of things.

[0:11:20.5] WJ: Yeah, I think it’s better to have major version upgrades that break relatively few things relatively often, rather than to have major version upgrades varying frequently that are massively different. It gets back to that idea of the upgrade path and how hard that is for people to find.

[0:11:39.0] KT: Yeah, and the marketing for the major versions matters a lot more.

[0:11:41.2] DA: Right. I mean I guess like you’re trying about infrequent major upgrade versions, like Java 9 just dropped a couple of weeks back. Who knows when enterprise Java adopters will ever like really jump on that?

[0:11:57.0] KT: Excited about Java 9?

[0:12:00.5] WJ: I’m not really care, excited about Java anything.

[0:12:02.8] KT: [inaudible 0:12:03.6]. It will be a little bit closer to being a real modern language.

[0:12:08.8] DA: But it still can’t parse JSON out of the box. Oh well. Soon, Java 10. Wait for it. Stay tuned.

[0:12:18.2] WJ: Have you guys looked at this Swiss train deployments that Ember has been doing?

[0:12:22.7] DA: What is that?

[0:12:23.3] WJ: This has been going on for a while. It’s super cool. They have three different channels, essentially. The first channel is Canary, and the way that works is it’s essentially master and it has absolutely all of the cutting edge features that people might want to alpha test, but it is understandably unstable. The only people who subscribe to that are people who want to help with the testing and people who really want to know what is coming out next. You might use it for a side project, but you definitely wouldn’t use it in production.

Then after the Canary release, comes the beta release, and all of these come out every six weeks, by the way. That is more stable, but it has newer features in it. Then six weeks after that comes the release build. The release build is guaranteed to work and you can put that in production safely.

[0:13:20.3] DA: That will be semantically versioned according to whatever the impact is.

[0:13:24.6] WJ: Yeah, they use semantic versioning. What’s nice about that is it’s a great way to solicit feedback from the community, which leads to gentler upgrade paths, and you can automate it all.

[0:13:40.6] KT: Chrome has a similar Canary system, right? Where they allow users to use the bleeding edge and poke the tires.

[0:13:47.6] WJ: Yeah. Chrome Canary, a lot of fun.

[0:13:50.8] KT: Their versions go up really, really fast, so it becomes a little less meaningful. But I think it’s still one of the healthiest C++ project I can think of in the open-source world, Chromium.

[0:14:00.3] DA: Yeah, their docs for contribution are very thick, very intense docs.

[0:14:05.7] KT: Impressive though.

[0:14:06.8] DA: Yeah, it definitely is. What version of Chrome are we on right now? Is it — What? 60, 61? Just burning through it.

[0:14:17.5] KT: Competing with Firefox directly.

[0:14:20.8] DA: Yeah, it’s like iPhone. Also, not quite semantically versioned anymore. Skipping the ninth release. Everyone kind of does that. When they get to 10, they’re like kind of very excited.

[0:14:33.5] KT: Windows 9 as well. Yeah, similar of the marketing reasons.

[0:14:40.0] WJ: I think that we ought to start just giving releases fun names for marketing purposes and then leave the major version number as just actually a technical detail.

[0:14:51.6] DA: Right, like how Android does it.

[0:14:53.6] WJ: Yeah, exactly.

[0:14:54.1] DA: I guess that’s technically semantically versioned as well, because they do have the major release and minor release and they’ll just come up with a marketing name for each release that they decide they need to market. Traces every minor and major release.

[0:15:11.0] KT: The Apple OS, macOS, is still on version 10 about 10 years later, right?

[0:15:18.0] DA: Technically. Is it a High Sierra?

[0:15:20.5] KT: OSX, right? It’s still 10.

[0:15:23.3] DA: Oh, okay.

[0:15:23.5] KT: They just stuck to that number.

[0:15:26.0] DA: I actually don’t know very much about the back versions of the operating system. Actually, I’m curious. How does that work with macOS? Someone can educate me. I know that they have some pretty sweet names —

[0:15:39.9] WJ: It used to be all fun cat names, and now it’s mountains.

[0:15:43.5] DA: Yeah, although I’m like less amped about upgrading from Sierra to High Sierra. It seems like it’s only an incremental upgrade.

[0:15:52.8] KT: Because it’s just an adjective?

[0:15:54.2] DA: Yeah, exactly. It’s like bigger Sierra.

[0:15:58.8] KT: I mean, I think it’s what they’re going for since it’s not a project that they sell in the first place.

[0:16:03.4] DA: Sure.

[0:16:04.8] KT: But I guess OSX was like their biggest breaking change of all times instead of switching to Intel architecture from macOS 8 and 9.

[0:16:13.9] DA: That’s true. I guess like there’s a guarantee that your new High Sierra should work with whatever you’re running right now, whatever hardware you have from them. Although I have heard problems with Puma and some other things on High Sierra, so there’s some pain being on the bleeding edge for sure.

[0:16:33.6] KT: Puma is a program for just serving web apps locally?

[0:16:37.9] DA: Yeah, for serving your Ruby on Rails applications.

[0:16:42.9] WJ: Has anybody worked on a project that automatically upgrades?

[0:16:47.8] DA: Oh, for dependency management?

[0:16:49.4] WJ: Yeah, because it’s really good for security. Also just good in general for the health of the project, because people don’t really remember to upgrade all of their packages.

[0:16:59.7] DA: Yeah. It does happen that eventually you’ve realized that you have all of these breaking changes and you’re very far behind, and if you have tests, then that’s great. You have a hand up in doing that upgrade. But if you don’t, then that’s a pretty scary process.

[0:17:15.1] WJ: Yeah. If you wait a whole year to do it or even six months, then you’ll have a lot of breaking changes to go through. Whereas if it’s a thing that runs on a nightly build, then when you come in in the morning, there’s just a ticket waiting for you, because the build failed and had to roll back. Or there’s nothing waiting for you because everything upgraded just fine.

[0:17:39.1] DA: Yeah, I really like that philosophy of just automating away the pain, because it really is. It’s not a fun thing. It’s a chore to do that.

[0:17:49.8] WJ: If it hurts, do it more, right? Isn’t that an Agile tenant?

[0:17:53.1] KT: I was able to do that on a node project, because we had a small audience and like we kind of built it ourselves in the beginning. We actually had — For node it had a smaller number of dependencies that it might have and things kind of just kept forward, and that part works fine. We had more problems with trying to get the right build packs from Heroku and like their setup than we did with the actual node packages.

[0:18:12.6] DA: Because Heroku was actually running behind the curve a bit?

[0:18:16.7] KT: Yeah. That would determine like the overall node version, but individual packages could move forward and had no problem.

[0:18:23.4] DA: Nice. Cool.

[0:18:26.2] WJ: Do we have any teach and learns today?

[0:18:28.0] DA: Yeah. I started taking a deep learning class on Coursera, the one from Stanford with Andrew Ng. Pretty excited about it. I also went to PyGotham last weekend and there were a number of good talks from people who are doing cool things with the neural networks, so I’m excited to have an excuse to play around with that a bit more.

[0:18:51.1] WJ: Oh, I’m jealous. I went to PyGotham, but I sat at a table the whole time and handed out materials.

[0:18:57.9] DA: Oh, to all are lovely people.

[0:18:59.7] WJ: Yeah. Then I got to talk with a lot of fun Pythonistas.

[0:19:04.1] KT: Do you feel like you have enough to actually build something, Dave?

[0:19:07.3] DA: Well, I just finished the intro videos. Those were pretty great. I feel like I have a lot of good context about the state of the art and where we came from and how we’re getting there. Yeah, there’s a lot of toolkits out there that you can use. I think I know enough to be dangerous.

[0:19:26.7] KT:  I love that.

[0:19:29.2] DA: Cool. Thank you guys for being here today. Kevin, it’s a pleasure having you today.

[0:19:34.7] KT: Thanks a lot.

[0:19:35.6] DA: William, always excellent.

[0:19:38.4] WJ: It was a pleasure to be here.

[0:19:40.0] DA: Thank you guys for listening to The Rabbit Hole. Hit us upon Twitter @radiofreerabbit. We’ll catch you guys next time.

Links and Resources:

Kevin Thomas

The Rabbit Hole on Twitter

Semantic Versioning

Swiss Train Deployments


Stanford Course on Corsera