nixpkgs/pkgs/top-level/release-lib.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

200 lines
6.6 KiB
Nix
Raw Normal View History

{ supportedSystems
, system ? builtins.currentSystem
, packageSet ? (import ../..)
, scrubJobs ? true
, # Attributes passed to nixpkgs. Don't build packages marked as unfree.
nixpkgsArgs ? { config = { allowUnfree = false; inHydra = true; }; }
}:
let
lib = import ../../lib;
inherit (lib)
addMetaAttrs
any
derivations
filter
flip
genAttrs
getAttrFromPath
hydraJob
id
isDerivation
lists
maintainers
mapAttrs
mapAttrs'
mapAttrsRecursive
matchAttrs
meta
nameValuePair
platforms
recursiveUpdate
subtractLists
systems
;
pkgs = packageSet (recursiveUpdate { inherit system; config.allowUnsupportedSystem = true; } nixpkgsArgs);
hydraJob' = if scrubJobs then hydraJob else id;
/* !!! Hack: poor man's memoisation function. Necessary to prevent
Nixpkgs from being evaluated again and again for every
job/platform pair. */
mkPkgsFor = crossSystem: let
packageSet' = args: packageSet (args // { inherit crossSystem; } // nixpkgsArgs);
pkgs_x86_64_linux = packageSet' { system = "x86_64-linux"; };
pkgs_i686_linux = packageSet' { system = "i686-linux"; };
pkgs_aarch64_linux = packageSet' { system = "aarch64-linux"; };
pkgs_riscv64_linux = packageSet' { system = "riscv64-linux"; };
pkgs_aarch64_darwin = packageSet' { system = "aarch64-darwin"; };
pkgs_armv6l_linux = packageSet' { system = "armv6l-linux"; };
pkgs_armv7l_linux = packageSet' { system = "armv7l-linux"; };
pkgs_x86_64_darwin = packageSet' { system = "x86_64-darwin"; };
pkgs_x86_64_freebsd = packageSet' { system = "x86_64-freebsd"; };
pkgs_i686_freebsd = packageSet' { system = "i686-freebsd"; };
pkgs_i686_cygwin = packageSet' { system = "i686-cygwin"; };
pkgs_x86_64_cygwin = packageSet' { system = "x86_64-cygwin"; };
in system:
if system == "x86_64-linux" then pkgs_x86_64_linux
else if system == "i686-linux" then pkgs_i686_linux
else if system == "aarch64-linux" then pkgs_aarch64_linux
else if system == "riscv64-linux" then pkgs_riscv64_linux
else if system == "aarch64-darwin" then pkgs_aarch64_darwin
else if system == "armv6l-linux" then pkgs_armv6l_linux
else if system == "armv7l-linux" then pkgs_armv7l_linux
else if system == "x86_64-darwin" then pkgs_x86_64_darwin
else if system == "x86_64-freebsd" then pkgs_x86_64_freebsd
else if system == "i686-freebsd" then pkgs_i686_freebsd
else if system == "i686-cygwin" then pkgs_i686_cygwin
else if system == "x86_64-cygwin" then pkgs_x86_64_cygwin
else abort "unsupported system type: ${system}";
2018-11-05 16:27:50 +00:00
pkgsFor = pkgsForCross null;
# More poor man's memoisation
pkgsForCross = let
examplesByConfig = flip mapAttrs'
systems.examples
(_: crossSystem: nameValuePair crossSystem.config {
inherit crossSystem;
pkgsFor = mkPkgsFor crossSystem;
});
native = mkPkgsFor null;
in crossSystem: let
candidate = examplesByConfig.${crossSystem.config} or null;
in if crossSystem == null
then native
else if candidate != null && matchAttrs crossSystem candidate.crossSystem
then candidate.pkgsFor
else mkPkgsFor crossSystem; # uncached fallback
# Given a list of 'meta.platforms'-style patterns, return the sublist of
# `supportedSystems` containing systems that matches at least one of the given
# patterns.
#
# This is written in a funny way so that we only elaborate the systems once.
supportedMatches = let
supportedPlatforms = map
(system: systems.elaborate { inherit system; })
supportedSystems;
in metaPatterns: let
anyMatch = platform:
any (meta.platformMatch platform) metaPatterns;
matchingPlatforms = filter anyMatch supportedPlatforms;
in map ({ system, ...}: system) matchingPlatforms;
assertTrue = bool:
if bool
then pkgs.runCommand "evaluated-to-true" {} "touch $out"
else pkgs.runCommand "evaluated-to-false" {} "false";
/* The working or failing mails for cross builds will be sent only to
the following maintainers, as most package maintainers will not be
interested in the result of cross building a package. */
crossMaintainers = [ ];
# Generate attributes for all supported systems.
forAllSystems = genAttrs supportedSystems;
# Generate attributes for all systems matching at least one of the given
# patterns
forMatchingSystems = metaPatterns: genAttrs (supportedMatches metaPatterns);
/* Build a package on the given set of platforms. The function `f'
is called for each supported platform with Nixpkgs for that
platform as an argument . We return an attribute set containing
a derivation for each supported platform, i.e. { x86_64-linux =
f pkgs_x86_64_linux; i686-linux = f pkgs_i686_linux; ... }. */
testOn = testOnCross null;
/* Similar to the testOn function, but with an additional
'crossSystem' parameter for packageSet', defining the target
platform for cross builds. */
testOnCross = crossSystem: metaPatterns: f: forMatchingSystems metaPatterns
(system: hydraJob' (f (pkgsForCross crossSystem system)));
2015-03-20 17:16:43 +00:00
/* Given a nested set where the leaf nodes are lists of platforms,
map each leaf node to `testOn [platforms...] (pkgs:
pkgs.<attrPath>)'. */
mapTestOn = _mapTestOnHelper id null;
_mapTestOnHelper = f: crossSystem: mapAttrsRecursive
(path: metaPatterns: testOnCross crossSystem metaPatterns
(pkgs: f (getAttrFromPath path pkgs)));
/* Similar to the testOn function, but with an additional 'crossSystem'
* parameter for packageSet', defining the target platform for cross builds,
* and triggering the build of the host derivation. */
mapTestOnCross = _mapTestOnHelper
(addMetaAttrs { maintainers = crossMaintainers; });
2015-03-20 17:16:43 +00:00
/* Recursively map a (nested) set of derivations to an isomorphic
set of meta.platforms values. */
packagePlatforms = mapAttrs (name: value:
if isDerivation value then
value.meta.hydraPlatforms
or (subtractLists (value.meta.badPlatforms or [])
(value.meta.platforms or supportedSystems))
2015-03-20 17:16:43 +00:00
else if value.recurseForDerivations or false || value.recurseForRelease or false then
packagePlatforms value
else
release-lib: Don't use tryEval for packagePlatforms This use of tryEval causes hydra to fully ignore evaluation failures of packages that occur while trying to evaluate the hydra platforms it should be built on. This includes failures that occur during evaluation of: - The `.type` attribute value - The `.meta.hydraPlatforms` or `.meta.platforms` attribute value - The `.version` attribute, since this can determine whether `.meta.position` is set - For non-derivations, `.recurseForDerivations` or `.recurseForRelease` Here's a minimal `release.nix` file, showcasing how a `.version` failure is ignored: let packages = pkgs: { success = pkgs.stdenv.mkDerivation { name = "success"; }; ignoredFailure = pkgs.stdenv.mkDerivation { pname = "ignored-failure"; version = throw "version error"; }; caughtFailure = pkgs.stdenv.mkDerivation { name = "caught-failure"; src = throw "src error"; }; }; releaseLib = import <nixpkgs/pkgs/top-level/release-lib.nix> { packageSet = args: packages (import <nixpkgs> args); supportedSystems = [ "x86_64-linux" ]; }; in releaseLib.mapTestOn (releaseLib.packagePlatforms releaseLib.pkgs) Evaluating this with `hydra-eval-jobs` before this change yields: $ hydra-eval-jobs release.nix -I nixpkgs=/path/to/nixpkgs warning: `--gc-roots-dir' not specified error: "error: --- ThrownError --- hydra-eval-jobs\nsrc error" { "caughtFailure.x86_64-linux": { "error": "error: --- ThrownError --- hydra-eval-jobs\nsrc error" }, "success.x86_64-linux": { "description": "", "drvPath": "/nix/store/q1sw933xd9bxfx6rcp0kqksbprj1wmwj-success.drv", "homepage": "", "isChannel": false, "license": "", "maintainers": "", "maxSilent": 7200, "nixName": "success", "outputs": { "out": "/nix/store/7awrz6hss4jjxvgbwi4wlyikncmslb7a-success" }, "schedulingPriority": 100, "system": "x86_64-linux", "timeout": 36000 } } Where you can see that there is no job for the `ignoredFailure` derivation. Compare this to after this change: $ hydra-eval-jobs release.nix -I nixpkgs=/path/to/nixpkgs warning: `--gc-roots-dir' not specified error: "error: --- ThrownError --- hydra-eval-jobs\nsrc error" error: "error: --- ThrownError --- hydra-eval-jobs\nversion error" { "caughtFailure.x86_64-linux": { "error": "error: --- ThrownError --- hydra-eval-jobs\nsrc error" }, "ignoredFailure": { "error": "error: --- ThrownError --- hydra-eval-jobs\nversion error" }, "success.x86_64-linux": { "description": "", "drvPath": "/nix/store/q1sw933xd9bxfx6rcp0kqksbprj1wmwj-success.drv", "homepage": "", "isChannel": false, "license": "", "maintainers": "", "maxSilent": 7200, "nixName": "success", "outputs": { "out": "/nix/store/7awrz6hss4jjxvgbwi4wlyikncmslb7a-success" }, "schedulingPriority": 100, "system": "x86_64-linux", "timeout": 36000 } } Notice how `ignoredFailure` is now part of the result.
2020-11-26 14:32:08 +00:00
[]
2015-03-20 17:16:43 +00:00
);
in {
/* Common platform groups on which to test packages. */
inherit (platforms) unix linux darwin cygwin all;
inherit
assertTrue
forAllSystems
forMatchingSystems
hydraJob'
lib
mapTestOn
mapTestOnCross
packagePlatforms
pkgs
pkgsFor
pkgsForCross
supportedMatches
testOn
testOnCross
;
}