From a90d993610ce555baedf4ef9b135a2eff941d868 Mon Sep 17 00:00:00 2001 From: Silvan Mosberger Date: Fri, 19 Jun 2026 17:00:08 +0200 Subject: [PATCH] ci/eval: Allow preventing internal Nixpkgs use of certain problem kinds --- ci/eval/chunk.nix | 1 + ci/eval/outpaths.nix | 18 ++++++ ci/eval/pre-eval.nix | 100 +++++++++++++++++++++---------- pkgs/stdenv/generic/problems.nix | 8 +++ pkgs/top-level/default.nix | 1 + pkgs/top-level/stage.nix | 1 + 6 files changed, 99 insertions(+), 30 deletions(-) diff --git a/ci/eval/chunk.nix b/ci/eval/chunk.nix index 4fabea659ad7..9bea26ce3180 100644 --- a/ci/eval/chunk.nix +++ b/ci/eval/chunk.nix @@ -18,6 +18,7 @@ let unfiltered = import ./outpaths.nix { inherit path; inherit includeBroken systems; + inherit (preEvalResult) attrPathsDisallowedForInternalUse; extraNixpkgsConfig = builtins.fromJSON extraNixpkgsConfigJson; }; diff --git a/ci/eval/outpaths.nix b/ci/eval/outpaths.nix index 6fcd22fc74a6..512290ce450a 100755 --- a/ci/eval/outpaths.nix +++ b/ci/eval/outpaths.nix @@ -14,6 +14,8 @@ builtins.readFile (path + "/pkgs/top-level/release-supported-systems.json") ), + attrPathsDisallowedForInternalUse ? [ ], + # Customize the config used to evaluate nixpkgs extraNixpkgsConfig ? { }, }: @@ -35,6 +37,22 @@ let allowVariants = !attrNamesOnly; checkMeta = true; + # We don't need to care about problems being caught using the + # standard mechanism, because any problems whose kind is not + # nixpkgsInternalUseAllowed cause the corresponding attributes to + # be disallowed entirely for internal use with + # attrPathsDisallowedForInternalUse, see also ./pre-eval.nix + problems.matchers = lib.mkForce [ + # We only need to set the broken handler to error, so that CI + # doesn't evaluate those. No reason it couldn't evaluate them + # afaik, but this is how it's been before. + { + kind = "broken"; + handler = "error"; + } + ]; + inherit attrPathsDisallowedForInternalUse; + # Silence the `x86_64-darwin` deprecation warning. allowDeprecatedx86_64Darwin = true; diff --git a/ci/eval/pre-eval.nix b/ci/eval/pre-eval.nix index 2d5a092747ad..eff8204a7bd5 100644 --- a/ci/eval/pre-eval.nix +++ b/ci/eval/pre-eval.nix @@ -1,5 +1,6 @@ # This file does a fast pre-evaluation of Nixpkgs to determine: # - paths: A *superset* of all attrpaths of derivations which might be part of a release on *any* platform. +# - attrPathsDisallowedForInternalUse: Attribute paths whose meta.problems has problems whose kinds should not be used internally in Nixpkgs # # This expression runs single-threaded under all current Nix # implementations, but much faster and with much less memory @@ -23,21 +24,25 @@ let # TODO: Use mapAttrsToListRecursiveCond when this PR lands: # https://github.com/NixOS/nixpkgs/pull/395160 - justAttrNames = + listAttrs = path: value: let result = if path == [ "AAAAAASomeThingsFailToEvaluate" ] || !(lib.isAttrs value) then [ ] else if lib.isDerivation value then - [ path ] + [ + { + inherit path value; + } + ] else lib.pipe value [ (lib.mapAttrsToList ( name: value: lib.addErrorContext "while evaluating package set attribute path '${ lib.showAttrPath (path ++ [ name ]) - }'" (justAttrNames (path ++ [ name ]) value) + }'" (listAttrs (path ++ [ name ]) value) )) lib.concatLists ]; @@ -50,39 +55,74 @@ let attrNamesOnly = true; }; - paths = [ - # Some of the following are based on variants, which are disabled with `attrNamesOnly = true`. - # Until these have been removed from release.nix / hydra, we manually add them to the list. - [ - "pkgsLLVM" - "stdenv" - ] - [ - "pkgsArocc" - "stdenv" - ] - [ - "pkgsZig" - "stdenv" - ] - [ - "pkgsStatic" - "stdenv" - ] - [ - "pkgsMusl" - "stdenv" - ] - ] - ++ justAttrNames [ ] outpaths; - + list = + map + (path: { + inherit path; + # This looks a bit weird, but the only reason we care about this value + # is for the meta.problems check below, and stdenv's certainly don't + # have any problems, so this is fine :) + value = { }; + }) + [ + # Some of the following are based on variants, which are disabled with `attrNamesOnly = true`. + # Until these have been removed from release.nix / hydra, we manually add them to the list. + [ + "pkgsLLVM" + "stdenv" + ] + [ + "pkgsArocc" + "stdenv" + ] + [ + "pkgsZig" + "stdenv" + ] + [ + "pkgsStatic" + "stdenv" + ] + [ + "pkgsMusl" + "stdenv" + ] + ] + ++ listAttrs [ ] outpaths; + paths = map (attrs: attrs.path) list; names = map lib.showAttrPath paths; + inherit (import ../../pkgs/stdenv/generic/problems.nix { inherit lib; }) + disallowNixpkgsInternalUseKinds + ; + + # Determine the list of attributes whose packages have any meta.problems + # with a kind that's disallowed from internal Nixpkgs use + attrPathsDisallowedForInternalUse = lib.pipe list [ + (lib.map ( + attrs: + attrs + // { + problematicProblems = builtins.tryEval ( + lib.filterAttrs (name: problem: disallowNixpkgsInternalUseKinds ? ${problem.kind}) ( + attrs.value.meta.problems or { } + ) + ); + } + )) + (lib.filter (attrs: attrs.problematicProblems.success && attrs.problematicProblems.value != { })) + (lib.map (attrs: { + attrPath = attrs.path; + reason = "it has certain meta.problems whose kinds are disallowed: ${ + lib.generators.toPretty { } attrs.problematicProblems.value + }"; + })) + ]; in { # TODO: Do we still need these? Probably not inherit paths names; result = { - inherit paths; + inherit paths attrPathsDisallowedForInternalUse; }; } diff --git a/pkgs/stdenv/generic/problems.nix b/pkgs/stdenv/generic/problems.nix index c7b6754d729d..e21f2126acbe 100644 --- a/pkgs/stdenv/generic/problems.nix +++ b/pkgs/stdenv/generic/problems.nix @@ -76,6 +76,7 @@ rec { maintainerless = { manualAllowed = false; isUnique = false; + nixpkgsInternalUseAllowed = true; automatic = { condition = # To get usable output, we want to avoid flagging "internal" derivations. @@ -98,6 +99,7 @@ rec { broken = { manualAllowed = true; isUnique = false; + nixpkgsInternalUseAllowed = true; automatic = { condition = config: @@ -122,11 +124,13 @@ rec { removal = { manualAllowed = true; isUnique = true; + nixpkgsInternalUseAllowed = false; automatic = null; }; deprecated = { manualAllowed = true; isUnique = false; + nixpkgsInternalUseAllowed = false; automatic = null; }; }; @@ -136,6 +140,10 @@ rec { # Problem kinds that are currently only allowed to be specified once uniqueKinds = lib.filterAttrs (name: value: value.isUnique) kinds; + disallowNixpkgsInternalUseKinds = lib.filterAttrs ( + name: value: !value.nixpkgsInternalUseAllowed + ) kinds; + automaticProblems = lib.mapAttrsToList (name: value: value.automatic // { kindName = name; }) ( lib.filterAttrs (name: value: value.automatic != null) kinds ); diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix index 4d44abadd961..4e19941441da 100644 --- a/pkgs/top-level/default.nix +++ b/pkgs/top-level/default.nix @@ -217,6 +217,7 @@ let fixedPoint = boot stages; pkgs = + # Generally only set by CI, don't want to cause a performance hit for users if config.attrPathsDisallowedForInternalUse == [ ] then fixedPoint else diff --git a/pkgs/top-level/stage.nix b/pkgs/top-level/stage.nix index 35929783e7c9..bc50a3f24247 100644 --- a/pkgs/top-level/stage.nix +++ b/pkgs/top-level/stage.nix @@ -314,6 +314,7 @@ let # See also ./default.nix, where these attributes are added back again so they're still checked by CI internallyDisallowedAttrPathsOverlay = final: prev: + # Generally only set by CI, don't want to cause a performance hit for users if config.attrPathsDisallowedForInternalUse == [ ] then { } else