5 ms·
If you're introducing breaking changes once per month, then your library really isn't ready. Tell people you have an unstable library. Breaking changes _will_
by Skinney 6y ago
If you're introducing breaking changes once per month, then your library really isn't ready.
Tell people you have an unstable library. Breaking changes _will_ happen. Then, when you've used your library in production for a while and are reasonably sure it wont have to change, tell people it's stable. If you make breaking changes after that, then start with a v2 suffix.
For some reason, semver has made people stop going through the alpha, beta and rc stages of a release, even though the point of such things is to discover breaking changes before you're commited to maintaining the version for the time to come.
Major version changes should be a rare event. If it's not, you're really just shipping around a (pre)alpha library, and should be explicit about that.
- barumi 6y ago> If you're introducing breaking changes once per month, then your library really isn't ready. The whole software industry moved away from waterfall to agile because it's unreasonable to assume that no requirements will emerge. I would disagree, for example, that Python3 is not ready just because they're introduced backward incompatible changes in some minor releases.
- tick_tock_tick 6y agoI mean python is basically the prime example of how to poorly manage version upgrades with their failure of 2 => 3.
- bigiain 6y agoThey were just desperate to do a better job of screwing up than Perl with it's 5 => 6 updates... <grin>
- masklinn 6y agoAs we can see from the Perl ecosystem having completely moved over to the extent that Perl 5 is now out of support while Python is still mired in the update.
- takeda 6y agoThat's funny, because I see the opposite. Perl 6 was a failure that had to be spun into a separate language and people stayed with perl 5, recently work on perl 7 started, but as far as I know perl 5 is still the version in use, recently FreeBSD forced me to update perl to version 5.32. Regarding Python, I no longer see 2.7 in the wild (I have no doubt it is still in some places) all projects I'm working on are in Python 3. AWS Lambda supports 3.8 (which is the latest stable version), Ubuntu comes with 3 installed by default. FreeBSD set 3.7 as default, depreciated and will remove 2.7 completely by the end of this year. Many Python 3 packages were released as python 3 only, the packages that that previously supported 2 dropped their support. Currently running 2.7 is a liability. Not as much that it is EOL and there are no security fixes anymore, but also packages dropping support (which is IMO a bigger deal).
- barumi 6y agoCan you provide a single example that supports your thesis that migration from Python 2 to 3 was poorly managed semver-wise? If anything, Python is chastised for having maintained two major versions in parallel without giving any compelling reason to force major rewrites on the while ecosystem.
- brabel 6y ago> The whole software industry moved away from waterfall to agile because it's unreasonable to assume that no requirements will emerge That's completely unrelated to library versioning. The software industry that I work at absolutely relies on library authors to diligently introduce breaking changes only in rare occasions, and preferably using semver to the extent possible. If you can't guarantee your library will be kept up-to-date with bug and security fixes, without me having to re-write my application on minor library updates because you decided to change your API to make it prettier, then I most certainly won't be using your library (indeed, I have removed dependencies from projects I worked on for this reason).
- nemothekid 6y ago>re-write my application on minor library updates This is the tension of semver - a minor library update might include a breaking change, but that doesn't mean you have to rewrite your application. For example, lets say I have a library that returned an int32 in a single function that would silently corrupt your data, but now has to return an int64. The right thing to do would be to issue a major upgrade where the function returns an int64. If you never used this function you wouldn't have to rewrite your application. Major updates in semver only mean backwards compatibility is broken, it doesn't mean it's am whole new api. To me, the Go approach takes your approach to major upgrades - reserve them for when you do something like rewriting the API. That's to me isn't a good assumption to bake in, I'd like to change a single function signature without having to copy my entire library to a new folder.
- Skinney 6y ago> To me, the Go approach takes your approach to major upgrades - reserve them for when you do something like rewriting the API. That's to me isn't a good assumption to bake in, I'd like to change a single function signature without having to copy my entire library to a new folder. Then make a new function within the same folder that works in a new way. If necessary, mark the old function as deprecated. An exception can be made if the function never worked to begin with, but that should really have been cought by tests or people using a pre-release version of the library.
- curryst 6y ago> The whole software industry moved away from waterfall to agile because it's unreasonable to assume that no requirements will emerge. There's also an insidious side effect that people tend to think of the more common semver of features than strict semver, and they associate versions with progress and effort. You could easily get to version 50.0.0 just sorting out finishing touches on the API with strict semver if you don't have good communication with the customer. Some enterprising middle manager will start asking you've spent 50 major versions worth of effort on this library or app. As a result of those effects and the unequal application of semver, I usually encourage people at work to choose other versioning schemes. Without strictly enforcing semver, there's really not a huge advantage to semver over a plain incrementing version. Incrementing versions also have the nifty feature of making it trivial to see how many versions behind you are. Or some people go with timestamped versions, which tells you how old your version is.
- hibbelig 6y agoI think GP was talking about internal software. Since business requirements are prone to change a lot, don’t blame the developers that the software needs to change.
- jacobvosmaer 6y agoI think the issue is about having to cross a module boundary, which is really about monorepo vs multirepo. You have much more freedom to make breaking changes when you don't need to cross a (repo/module) boundary. I think the Go module system encourages you to avoid adding unnecessary boundaries. As someone else pointed out already, one of the problems is that you don't find out that boundaries are bad until you hit v2, and then you discover that you have this chunk of technical debt (unnecessary repo boundaries that slow down development) that you didn't know about.
- Skinney 6y agoWere I work we have several internal libraries. When we crossed the point were one library was used in more than 3 services, we stopped doing breaking changes because it was simply to time consuming to upgrade to the next major version of the package. Imagine spending an significant portion of your day migrating all your internal apps to the latest major version of an internal package, then you can imagine what we faced once a month. We stopped doing breaking changes after a while. Instead we're effectively doing versioning at the module level. If module A could really use a fixup, we make an entirely new module A.V2, and start using that in new code. Things that don't need the new functionality can keep using the old API, which still works, and upgrade whenever we have some extra time (we never have extra time) or we really _really_ need to. We've also adopted a policy that nothing gets added to our internal packages before they've been used in an application for a certain amount of time. Code duplication between applications is fine if we don't know exactly how the API should work, that way you have flexibility to change the code to fit a specific use case for a specific application. If that common functionality really has to be common _straight_ away (which we surprisingly haven't hit yet) we could place it in a module A.Unstable to make certain everyone knows that it can break at any point. In either case. It's just as important to avoid breaking changes in internal software as in everywhere else. Breaking changes are not free, except for the library authors.
- sagichmal 6y agoYou don't get to define what "ready" means for me. I get to define that, as the author of the package.