Skip to content

[WIP] Deprecation warnings for maintainerless leaf packages#531180

Draft
infinisil wants to merge 14 commits into
NixOS:masterfrom
tweag:maintainerless-leafs
Draft

[WIP] Deprecation warnings for maintainerless leaf packages#531180
infinisil wants to merge 14 commits into
NixOS:masterfrom
tweag:maintainerless-leafs

Conversation

@infinisil

@infinisil infinisil commented Jun 12, 2026

Copy link
Copy Markdown
Member

This implements part of the approved NixOS/rfcs#180 (rendered): Adding warnings to packages that both have no maintainers and are (definitely) leaf packages.

The goal of this is to either prompt users of packages to become maintainers, or to drop the packages if that doesn't happen.

With this PR, I invite you to try out this branch in your own NixOS configuration and report how well it works. Note that the branch is outdated by about a month, so don't actually deploy your machines with this :)

How it works

  • Adds a check to CI that ensures that meta.hasNoMaintainersButDependents for accessible packages is set only if the package has no maintainers and the package attribute is referenced anywhere in Nixpkgs outside of the package definition itself
  • Enables maintainerless deprecation warnings by default for packages that have no maintainers and where meta.hasNoMaintainersButDependents is not set.

Some consequences are:

  • It is not perfect: If {}.hello appears somewhere and pkgs.hello is maintainerless, CI requires pkgs.hello.meta.hasNoMaintainersButDependents to be set. Imo this is fine because it's only annoying for maintainerless packages.
  • If hello is a maintainerless leaf package and a PR adds it as a dependency to another package, that PR will also have to set hello.meta.hasNoMaintainersButDependents. Similarly it needs to be unset again if the dependency is removed again.

Most notably this approach causes effectively no additional burden for committers, and instead pushes all the continuous maintenance to package maintainers via CI.

FAQ

  • Why not meta.hasNoMaintainersNorDependents? Because
    • It would create would create a larger diff, and wouldn't allow listing unmaintained non-leaf packages by grepping
  • Why not meta.hasNoDependents/meta.isLeaf? Because:
    • It would cause churn for maintained packages as well
  • Why not have a ~weekly evaluation of which packages are leafs and expose that information into Nixpkgs so it can add warnings automatically? Because
    • This is extra regular work for committers
    • There's no universal way to add warnings to arbitrary packages that doesn't add a big performance overhead
    • It means eval warnings are out of date by up to a week
  • Why not warn for all maintainerless packages in environment.systemPackages? This would be much easier to implement, because there's no need to check whether packages are leafs. Because:
    • Does not warn for non-systemPackages uses, including:
      • Development environments
      • During Nixpkgs testing using nix-build -A and co.
      • Library packages that wouldn't make sense to add to systemPackages, such as pythonPackages or C libraries
    • Consequently, without warning all users about it, this does not enable eventual removal of maintainerless packages from Nixpkgs as laid out by RFC 180
    • Unable to use meta.problems -> need another separate mechanism for triggering warnings and changing severities
  • Why not determine which packages are leafs by using a full Nixpkgs evaluation, e.g. using nix-eval-jobs --show-input-drvs and checking which derivations are not inputDrvs of any other derivations? Because:
    • This would give false positives about leaf packages, because it can't detect references from NixOS modules (and possibly more). If we want automation to be able to eventually remove leaf packages, we need to minimise false positives, which are almost inexistent with the approach here
    • Doing this for all PRs would slow down Nixpkgs evaluation a lot (at least currently, it should be fixable, see here)

TODO

  • Set meta.hasNoMaintainersButDependents = true where needed. This was assistent with ast-grep to satisfy the below two points
  • Ran the nixpkgs-vet branch on this Nixpkgs branch successfully. CC @NixOS/nixpkgs-ci
  • Ensure that CI catches when non-top-level packages give maintainterless deprecation warnings.
  • Ensure that CI catches internal use of problematic dependencies: Allow meta.problems while preventing internal use of certain kinds #533376 and ci/eval: Allow disallowed attrs to depend on other disallowed attrs #537051, this PR is based on top of those
  • Evaluated my own NixOS configuration to ensure only warnings for unmaintained leaf packages I'm using are triggered
  • Improve error messages
  • Get some stats on number of affected packages, and differences between approaches
  • Settled on the details of how hasNoMaintainerButDependents and co. should be named, as well as error messages
  • Make a Discourse post for more noise
  • Consider whether third-party tooling will have problems with this
  • Cleaned up and merged the nixpkgs-vet code
  • Wrote documentation and release notes

No AI tools were used to create this PR.

@infinisil infinisil added the 1.severity: significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. label Jun 12, 2026
@llakala

llakala commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Before further progress on this, can you please review
#519600? I also see several performance pitfalls in this PR. Depending on outputsMeta will require forcing the value of the generated meta, which is very bad for performance.

@nixpkgs-ci nixpkgs-ci Bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jun 12, 2026
@infinisil infinisil force-pushed the maintainerless-leafs branch from 677425c to 97c31c3 Compare June 24, 2026 12:55
@nixpkgs-ci nixpkgs-ci Bot added 2.status: merge conflict This PR has merge conflicts with the target branch and removed 2.status: merge conflict This PR has merge conflicts with the target branch labels Jun 24, 2026
@infinisil infinisil force-pushed the maintainerless-leafs branch from 97c31c3 to 3a14a53 Compare June 29, 2026 15:21
@nixpkgs-ci nixpkgs-ci Bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Jun 29, 2026
infinisil added 12 commits June 30, 2026 16:17
With a dependency chain like

    a -> b -> c

it was not possible to e.g. add a `meta.problems.removal` to b, because that would cause b to be entirely unavailable as a dependency.

This PR slightly lifts that restriction by allowing both a and b to be marked with such a problem without causing a CI failure.

This is useful for:
- Having a problem on a package that needs to be removed but still has dependents (which then also need a problem)
- Having a problem on a package that is aliased under another attribute, which counts as a dependency
This enforces that any packages that are evaluated can't depend on other
evaluated attributes that have problems
@infinisil infinisil force-pushed the maintainerless-leafs branch from 3a14a53 to 8e6e01f Compare June 30, 2026 14:30
Before, something like

  nativeBuildInputs = [
    (runCommand "dep" { meta.description = "Dep"; } "")
  ];

would cause an eval warning without failing CI

After this change, CI ensures that when evaluating the set of packages
that don't have internally disallowed problem kinds, no such problem
kinds are present.
Entirely guided by nixpkgs-vet and `nix-build ci -A eval.singleSystem`
(on x86_64-linux)
@infinisil infinisil force-pushed the maintainerless-leafs branch from 70f574f to 77b04e1 Compare June 30, 2026 15:45
@infinisil

Copy link
Copy Markdown
Member Author

While this PR is not entirely done just yet, the fundamentals are looking really good right now. After #533376 and #537051 (which this PR includes as the first commit right now), as well as some commits in here, all treewide changes needed are fully checked by CI. While some errors aren't ideal just yet, they can be improved still.

Since I'm leaving Tweag after today, I won't have as much time to work on this anymore. In case I'm not able to finish this myself, here's the main bits of context to know:

  • This still depends on this messy but functional nixpkgs-vet branch. That currently serves as a PoC, but before this PR can be merged, the nixpkgs-vet changes need to be upstreamed, released and landed in Nixpkgs with a ci/pinned.json bump

  • After rebasing, make sure to run the above nixpkgs-vet version, I use:

    cargo run --release -- --base tests/empty-base/main ~/src/nixpkgs
    
    • If it gives NPV-180 as an error, add meta.hasNoMaintainersButDependents = true; to the respective package
    • For NPV-18{1-3}, remove meta.hasNoMaintainersButDependents
  • Furthermore after rebasing, run nix-build ci -A eval.singleEval (it's also what CI does already)

    • If you get an abort like "not allowed internally in Nixpkgs", check the stack trace to find the package that depends on the internally disallowed package. To resolve, either remove the dependency on the disallowed package or remove the problem on the disallowed package itself.
    • If you get maintainerless warnings (which fail CI), add meta.hasNoMaintainersButDependents to the maintainerless packages (generally these are non-exposed locally-defined packages)
  • Sometimes packages inherit meta from another package, in which case meta = other.meta // { hasNoMaintainersButDependents = true/false; } is necessary to address CI failures.

  • The only known cases of nixpkgs-vet not being able to detect dependents (and can therefore wrongly require removal of hasNoMaintainersButDependents) is when package sets are used with lib.attrValues. See the "treewide: Add requiresMaintainers where necessary" commit for some examples of this, as well as package sets that are generated (which don't need maintainers nor a deprecation warning, even if they don't have any dependents).

  • CI fails right now, but can be easily made to pass by following the above

Furthermore, the PR description has a lot of general info and the remaining TODOs.

@nixpkgs-ci nixpkgs-ci Bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.severity: significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. 2.status: merge conflict This PR has merge conflicts with the target branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants