Because dependencies are not perfectly managed / versioned. When you release the end product app, you have 3 options:
- assume that your published version compatibility is correct and let the app fail for some library upgrade in the future
- publish a strict list of dependency versions and keep updating it
- publish a strict list of dependency versions and rely on old versions as long as possible
The first one results in unhappy users, second one in lack of distro packages because you rely on too recent deps, third one either in lack of distro packages because of too old deps or in unhappy users because deps don't work on their new system anymore. There's no way to satisfy everyone unless distributions themselves become aware of multiple levels of package management.
I am always surprised when I hear of developers letting new versions of dependencies go into production. I cannot imagine taking such a chance.
Even if every new version of the total app is tested heavily before production, you lose the inherent stability of shipping the same code that is known stable from the users over time.
Others have said it is important to use new versions of dependencies to get the bug fixes but I don't see that as a good trade-off.
In practice the apps that don’t publish updated dependency lists are also the ones that end up breaking by when you do update their dependencies. It only works in the simplest of patch versions.
- dependency versions being fixed is a feature. I've had package installs fail because a dependency published a semver-compatible update that broke something. In a web context this would break the app until the dependency pulled the update or the dependent pushed an update disallowing that version.
A package manager can't run my tests and confirm that my code doesn't break with the newer version of the lib (just because it supposedly has no breaking changes doesn't mean it works.... there are a surprisingly large number of behaviors that consumers can rely on that go way beyond just the provided API).
So, all you're really automating is me going to look at the package's homepage and seeing if there's a new version. I'd still have to read the changelist to see if the bug that concerns me is fixed, what other changes are included, and run all my tests (and possibly write new ones). This is automating the easiest part of upgrading a dependency.
The problem is the technical debt you acquire this way.
Eventually you're going to need to upgrade X for a security fix, but the new version of X isn't compatible with the version of Y you are using, and upgrading that would break Z, and Z would break your app here and here. Now you're spending a couple weeks trying to do the upgrade to get a security fix that was 0 day two weeks ago, when you should have been writing things that actually advanced your app instead.
I keep my dependencies up to date, and consider it technical debt when they are not, and would never want to go back.
I’m not really sure this is an entirely fair argument.
If you rely on third party packages of any type, you have dependencies that can rapidly and unexpectedly break with an update. Semantic versioning is supposed to help with this, but it doesn’t always help.
Not OP, but a couple guesses off the top of my head:
* It becomes a more painful process to upgrade dependencies (have to find/replace across your codebase).
* Many versions of the same library get pulled in. If you depend on package@1.5.3 and a dependency of yours depends on package@1.5.4, that's twice the dependency size as compared to both just using 1.5.4. This matters more in the case of web app bundle size though than running local programs.
Often, package is built using a certain library version (from a different package), that library is then updated - and the new package cannot build using the new library.
Or... deeper parts of the compiler toolchain change, and the application doesn't re-build without changes.
One reason is that many developers work with package managers / languages that are INCAPABLE of handling multiple versions of the same dependency. Without this you quickly get version deadlocks without semver.
Another reason is that many developers are obsessing on getting the latest version of their dependencies for fear of security issues or just missing out on the latest and greatest - and they often completely ignore retesting the application since they now have someone to blame if it fails (that other developer should not have pushed the breaking change with a minor version bump!)
I agree with you that it should be the standard to have fixed versions and update your dependencies at a time of your choosing so that everything can get tested properly - but it seems to be an uphill battle.
The reason it's dangerous is that packages can introduce backwards incompatible changes. If you have a project that you don't work on for a few weeks/months and then need to fix a bug, you're going to have to spend additional cycles tracking down the issue and fixing either the backwards incompatible change, or adding a specific version to your requirements file anyway.
I like to try and scope the package versions at the level the maintainer promises not to introduce breakages at.
Do you not depend on a specific version? Do you not use checksums for dependencies?
reply