Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

How should we go about backwards compatibility? #81

Open
bendlas opened this issue Sep 26, 2024 · 5 comments
Open

How should we go about backwards compatibility? #81

bendlas opened this issue Sep 26, 2024 · 5 comments
Labels
question Further information is requested

Comments

@bendlas
Copy link

bendlas commented Sep 26, 2024

Question

Currently, we seem to be promising compatibility for stable branches, but in new releases, we are allowed to break "if necessary". Where do you think the line of "if necessary" should fall?

How close do you think we can with long-term backwards compatibility - to the Clojure ideal [1] - given the scale of nixpkgs?

Can you answer specifically about NixOS module options, as well as generally for nix community projects?

[1] "There are only two ways to change software: growing it and breaking it. We don't break."

Candidates I'd like to get an answer from

No response

Reminder of the Q&A rules

Please adhere to the Q&A guidelines and rules

@bendlas bendlas added the question Further information is requested label Sep 26, 2024
@illustris
Copy link

illustris commented Sep 28, 2024

There are two parts to this problem:

  1. Establishing clear policies
  2. Enforcing these policies

I recognize that sometimes, breaking changes are unavoidable. I've also made changes from time to time without paying attention to backwards compatibility. But I lean towards avoiding breaking changes whenever possible, aligning with the Clojure ideal of growing without breaking. When changes are necessary, they should be introduced thoughtfully. Some of the things we can do here are:

  • Deprecation warnings: Introduce warnings at least one stable release before implementing a breaking change. This gives users more time to adapt.
  • Utilize system.stateVersion or something similar to maintain compatibility with options that might have changed.
  • Minimize Breakages: Reserve breaking changes for critical issues that cannot be resolved through extension or deprecation.

To put these into practice, we could:

  • Integrate checks into CI to track changes to existing options and flag potential breaking changes
  • Add any guidelines we reach consensus on to contributing.md

Achieving perfect long-term backward compatibility is practically impossible given the scale of nixpkgs. But we can get closer to this ideal by setting policies and leveraging tools to enforce them. By prioritizing stability and careful growth, we maintain user trust and make the ecosystem more robust for everyone.

@getchoo
Copy link
Member

getchoo commented Oct 2, 2024

Where do you think the line of "if necessary" should fall?

First and foremost, breaking changes should only be introduced if there's a clear (large) benefit to the usage of the module options, package/lib attributes, etc. When this does occur, backwards compatibility should be implemented via aliases or small wrapper layers unless it is deemed too large of a maintenance burden, or the change is such is so large that it isn't feasible to use either

How close do you think we can with long-term backwards compatibility - to the Clojure ideal [1] - given the scale of nixpkgs?

I don't think breakages will ever be avoidable, nor will we be able to adopt something similar to Hickey's idea of only growing our collection. However, a lot of tools in nixpkgs -- like pkgs/top-level/aliases.nix and especially functions in our module library such as mkMergedOptionModule and mkAliasOptionModule -- can get us to an approximation of not removing user-facing interfaces that will ease the stress of breaking changes over time

And as said above by illustris, CI checks to flag breaking changes can also assist here by ensuring things are only broken when we explicitly intend to, it's necessary (as defined by above), and that there are no better paths to retaining backwards compatibility according to not just the author, but the wider contributor base. Some prior art here is the Rust community's Crater project, which runs automated tests across crates in their ecosystem and compares the results between a new and older version of the compiler

(Also small side note: thanks for linking that keynote! It's been a good listen and I plan on finishing it tonight now :p)

@phaer
Copy link
Member

phaer commented Oct 6, 2024

I am happy and always open about specific proposals, as an RFC or other-wise, to improve "backwards-compatibility"; but I don't think it's an urgent problem at this point in time.

NixOS is much better than most other systems in allowing you to build and/or switch back to quite old releases, even with a binary cache still available!

Keeping stability in terms of code is a much broader topic. I think the policy to allow breakage between releases is a good one, but you are right that we should elaborate that "if necessary" part.

  • I think it's good that it's in there, if only as a small reminder to reconsider whether the author thinks "its necessary" to break compat.
  • A more elaborate policy should probably be different between subsets of nixpkgs (i.e. lib, nixos, services)
  • Its IMO fine to break backwards-compat if it ends up with the right warnings/assertions for user config, a changelog and ideally a VM test for the service :)

@proofconstruction
Copy link
Contributor

Nix offers an unparalleled story for backwards compatibility, or it could, with some architectural changes (and should!). It's entirely reasonable to expect that a future iteration will enable module- or even function-level version pinning, allowing for trivial backwards compatibility of critical components while the rest of the system moves forward.

I'm happy to stick to the current pattern of ensuring compatibility for supported stable branches while allowing for breaking changes in the unstable branches.

Projects under the nix-community organization, unofficial as they are, have different expectations. As I answered in #11, I consider nix-community to be the development and staging ground for new feature additions to the main projects. While the specific details of those features are worked out, one should expect possibly-frequent breaking changes.

In #16 I discussed the full-reproducibility goal, and this applies here also: achieving perfect bitwise reproducibility will go a long way towards satisfying some maximal vision of backwards-compat.

@jtojnar
Copy link
Member

jtojnar commented Oct 7, 2024

I would leave this up to the individual maintainers of the affected components. Maintaining backwards compatibility can be a pain and they are the people who actually do the job. Though I would still recommend providing a clear migration path in the contributing documentation whenever practical.

@NixOS NixOS locked as resolved and limited conversation to collaborators Oct 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants