mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-11-09 16:18:34 +01:00
This creates a simple mapping of all packages to github ids of all their maintainers. This is uploaded as an artifact and is then available for download on the latest commit of each branch with a merge queue. This will allow scheduled jobs to use this information for setting maintainer-related labels, to request reviewers and to implement the merge-bot. The advantage over querying this information directly via Nix in each case: The scheduled job does not need to install Nix and does not need to checkout the target branch. Compared to obtaining the maintainer information just for a single PR during Eval, this will allow retroactively changing maintainers for a package: For example, it allows to request a new maintainer as reviewer for a PR that was created before they became maintainer, but is still open - and similarly for maintainer labels and merge-bot rights. None of these extensions are implemented by this PR, yet.
112 lines
3.6 KiB
Nix
112 lines
3.6 KiB
Nix
{
|
|
lib,
|
|
runCommand,
|
|
writeText,
|
|
}:
|
|
|
|
{
|
|
beforeDir,
|
|
afterDir,
|
|
evalSystem,
|
|
}:
|
|
|
|
let
|
|
# Usually we expect a derivation, but when evaluating in multiple separate steps, we pass
|
|
# nix store paths around. These need to be turned into (fake) derivations again to track
|
|
# dependencies properly.
|
|
# We use two steps for evaluation, because we compare results from two different checkouts.
|
|
# CI additionalls spreads evaluation across multiple workers.
|
|
before = if lib.isDerivation beforeDir then beforeDir else lib.toDerivation beforeDir;
|
|
after = if lib.isDerivation afterDir then afterDir else lib.toDerivation afterDir;
|
|
|
|
/*
|
|
Computes the key difference between two attrs
|
|
|
|
{
|
|
added: [ <keys only in the second object> ],
|
|
removed: [ <keys only in the first object> ],
|
|
changed: [ <keys with different values between the two objects> ],
|
|
rebuilds: [ <keys in the second object with values not present at all in first object> ],
|
|
}
|
|
*/
|
|
diff =
|
|
old: new:
|
|
let
|
|
filterKeys = cond: attrs: lib.attrNames (lib.filterAttrs cond attrs);
|
|
oldOutputs = lib.pipe old [
|
|
(lib.mapAttrsToList (_: lib.attrValues))
|
|
lib.concatLists
|
|
(lib.flip lib.genAttrs (_: true))
|
|
];
|
|
in
|
|
{
|
|
added = filterKeys (n: _: !(old ? ${n})) new;
|
|
removed = filterKeys (n: _: !(new ? ${n})) old;
|
|
changed = filterKeys (
|
|
n: v:
|
|
# Filter out attributes that don't exist anymore
|
|
(new ? ${n})
|
|
|
|
# Filter out attributes that are the same as the new value
|
|
&& (v != (new.${n}))
|
|
) old;
|
|
# A "rebuild" is every attrpath ...
|
|
rebuilds = filterKeys (
|
|
_: pkg:
|
|
# ... that has at least one output ...
|
|
lib.any (
|
|
output:
|
|
# ... which has not been built in "old" already.
|
|
!(oldOutputs ? ${output})
|
|
) (lib.attrValues pkg)
|
|
) new;
|
|
};
|
|
|
|
getAttrs =
|
|
dir:
|
|
let
|
|
raw = builtins.readFile "${dir}/${evalSystem}/paths.json";
|
|
# The file contains Nix paths; we need to ignore them for evaluation purposes,
|
|
# else there will be a "is not allowed to refer to a store path" error.
|
|
data = builtins.unsafeDiscardStringContext raw;
|
|
in
|
|
builtins.fromJSON data;
|
|
|
|
beforeAttrs = getAttrs before;
|
|
afterAttrs = getAttrs after;
|
|
diffAttrs = diff beforeAttrs afterAttrs;
|
|
diffJson = writeText "diff.json" (builtins.toJSON diffAttrs);
|
|
|
|
# The maintainer list is not diffed, but just taken as is, to provide a map
|
|
# of maintainers on the target branch. A list of GitHub IDs is sufficient for
|
|
# all our purposes and reduces size massively.
|
|
meta = lib.importJSON "${after}/${evalSystem}/meta.json";
|
|
maintainers = lib.pipe meta [
|
|
(lib.mapAttrsToList (
|
|
k: v: {
|
|
# splits off the platform suffix
|
|
package = lib.pipe k [
|
|
(lib.splitString ".")
|
|
lib.init
|
|
(lib.concatStringsSep ".")
|
|
];
|
|
maintainers = map (m: m.githubId) v.maintainers or [ ];
|
|
}
|
|
))
|
|
# Some paths don't have a platform suffix, those will appear with an empty package here.
|
|
(lib.filter ({ package, maintainers }: package != "" && maintainers != [ ]))
|
|
];
|
|
maintainersJson = writeText "maintainers.json" (builtins.toJSON maintainers);
|
|
in
|
|
runCommand "diff" { } ''
|
|
mkdir -p $out/${evalSystem}
|
|
|
|
cp -r --no-preserve=mode ${before} $out/before
|
|
cp -r --no-preserve=mode ${after} $out/after
|
|
# JSON files will be processed above explicitly, so avoid copying over
|
|
# the source files to keep the artifacts smaller.
|
|
find $out/before $out/after -iname '*.json' -delete
|
|
cp ${diffJson} $out/${evalSystem}/diff.json
|
|
cp ${maintainersJson} $out/${evalSystem}/maintainers.json
|
|
''
|