From aea28263d435db2fe27cee5fa055196a20132232 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 2 Dec 2023 21:48:43 -0800 Subject: [PATCH 1/6] ct: init This commit adds , a single entry point for all Continuous Testing (CT) runners, whether they are github, gerrit, ofborg, or something else. After merging this commit to create , we will gradually migrate the existing CT runners so that they use this interface and *only* this interface. This will ensure that all CT actions can be reproduced locally by individual developers without needing access to special infrastructure. --- .github/CODEOWNERS | 3 ++ ct/default.nix | 28 +++++++++++++++++++ ct/tasks.nix | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100755 ct/default.nix create mode 100644 ct/tasks.nix diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 78e56796425dcf5..bd427f0eb779dfd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -18,6 +18,9 @@ # EditorConfig /.editorconfig @Mic92 @zowoq +# single entry point for Continuous Testing (CT) runners (ofborg, github, etc) +/ct @infinisil @amjoseph-nixpkgs + # Libraries /lib @infinisil /lib/systems @alyssais @ericson2314 @amjoseph-nixpkgs diff --git a/ct/default.nix b/ct/default.nix new file mode 100755 index 000000000000000..65b37b66ee1a653 --- /dev/null +++ b/ct/default.nix @@ -0,0 +1,28 @@ +#!/usr/bin/env nix-shell +#!nix-shell -I nixpkgs=. ./. --pure --run true + +# +# This file is the single entry point for all CT (Continuous +# Testing) in nixpkgs. CT is defined to be those checks which +# should be run upon every set of commits before they are merged. +# +# Neither this file nor anything else in the ./ct directory are +# stable interfaces of nixpkgs. If you depend on anything other +# than the exit code returned by `./ct/default.nix` you need to be +# prepared to respond to and deal with breakage. +# +# All CT runners (ofborg, gerrit, github actions, etc, etc) should +# be configured to invoke this file, which should in turn perform +# the requested action. CT actions must be runnable locally, +# i.e. by an ordinary developer using a nixpkgs checkout. Please do +# not write forge-specific/ofborg-specific CT actions. If you need +# to pass arguments please use `--arg`; we clear the environment +# with `--pure`. +# + +{ ... +}@args: + +import ./tasks.nix args + + diff --git a/ct/tasks.nix b/ct/tasks.nix new file mode 100644 index 000000000000000..f35a6b77d1bdda7 --- /dev/null +++ b/ct/tasks.nix @@ -0,0 +1,70 @@ +# +# This derivation builds a Makefile, which is then passed to gmake +# in order to perform the necessary CT tasks, with correct +# dependency ordering and as much parallelism as possible. +# +# A Makefile is used solely because we need access to the Nix store +# (which contains cached artifacts from previous CT runs) in order +# to get reasonable performance. Since recursive-nix is neither +# stable nor ready for use, a Makefile is the simple interim solution. +# +# The Makefile contains one big target which runs nix-build on +# several attributes. In general you should try to express your CT +# target by adding additional attributes to this list. Please add +# new Makefile targets or shellscript only as a last resort. +# + +{ pkgs-path ? ../. +, shortRev ? builtins.substring 0 8 (lib.commitIdFromGitRepo ../.git) +, pkgs ? import pkgs-path {} +, lib ? pkgs.lib +}: + +let + + # Attrset where the attrname is the target name and the attrvalue + # becomes the lines to be used. No tab characters needed. + # + # These commands are executed "outside of" nix-build, so they have + # access to the shared store which will retain cached artifacts + # across CT runs. + # + targets = { + pkgs-test-release ='' + ${pkgs.nix}/bin/nix-build ./pkgs/test/release + ''; + + /* + libtests = '' + ${pkgs.nix}/bin/nix-build ./lib/tests/release.nix + ''; + */ + }; + +in +pkgs.mkShell { + pname = "nixpkgs-ct"; + version = shortRev; + + passAsFile = [ "makefile" ]; + makefile = '' + ${lib.concatStrings + (lib.mapAttrsToList + (name: val: + '' + .PHONY: ${name} + default: ${name} + ${name}: + ${lib.concatStringsSep "\n" + (map (line: if line=="" then "" else "\t${line}") + (lib.splitString "\n" val))} + '') + targets)} + ''; + + shellHook = '' + unset shellHook + set -eu -o pipefail + ${pkgs.gnumake}/bin/make -k -j -f $makefilePath default + ''; +} From 80b3ee08dee10fd7c7cb52c53db5f00a4ec0be79 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 2 Dec 2023 21:50:11 -0800 Subject: [PATCH 2/6] lib/tests/release.nix: add temporary hook to Ofborg is out-of-repo and has a much smaller (and therefore less responsive) committer team. Since it takes a long time to get them to merge and redeploy, this commit adds a TEMPORARY call from lib/tests/release.nix to the top-level ct entry point. This commit should be reverted as soon as ofborg merges and deploys the following PR, which will cause it to invoke the entry point directly: https://github.com/NixOS/nixpkgs/pull/269356 --- lib/tests/release.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/tests/release.nix b/lib/tests/release.nix index 843180490bb2b2b..218e9056004b2de 100644 --- a/lib/tests/release.nix +++ b/lib/tests/release.nix @@ -67,5 +67,18 @@ let in pkgs.symlinkJoin { name = "nixpkgs-lib-tests"; - paths = map testWithNix nixVersions; + paths = map testWithNix nixVersions ++ + + # + # TEMPORARY MIGRATION MECHANISM + # + # This comment and the expression which follows it should be + # removed once the following PR has merged to ofborg and been + # deployed: + # + # https://github.com/NixOS/ofborg/pull/660 + # + [(import ../../pkgs/test/release {})] + ; + } From eb6fca5848aeab7bb1ed03d3439fb6a915b9fe9e Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 2 Dec 2023 22:12:51 -0800 Subject: [PATCH 3/6] lib/tests/release.nix: revert temporary migration mechanism --- lib/tests/release.nix | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/lib/tests/release.nix b/lib/tests/release.nix index 218e9056004b2de..843180490bb2b2b 100644 --- a/lib/tests/release.nix +++ b/lib/tests/release.nix @@ -67,18 +67,5 @@ let in pkgs.symlinkJoin { name = "nixpkgs-lib-tests"; - paths = map testWithNix nixVersions ++ - - # - # TEMPORARY MIGRATION MECHANISM - # - # This comment and the expression which follows it should be - # removed once the following PR has merged to ofborg and been - # deployed: - # - # https://github.com/NixOS/ofborg/pull/660 - # - [(import ../../pkgs/test/release {})] - ; - + paths = map testWithNix nixVersions; } From 55834bb8cab6ae57c2ed05947ff9b457f5c605d6 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 2 Dec 2023 22:13:22 -0800 Subject: [PATCH 4/6] ct/tasks.nix: invoke lib/tests/release.nix from single CT entry point --- ct/tasks.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/ct/tasks.nix b/ct/tasks.nix index f35a6b77d1bdda7..971d3df83af9aff 100644 --- a/ct/tasks.nix +++ b/ct/tasks.nix @@ -34,11 +34,9 @@ let ${pkgs.nix}/bin/nix-build ./pkgs/test/release ''; - /* libtests = '' ${pkgs.nix}/bin/nix-build ./lib/tests/release.nix ''; - */ }; in From 4efe5ca489f28f7e249e8a1bcf9e62cd319c3a09 Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Thu, 23 Nov 2023 05:00:26 -0800 Subject: [PATCH 5/6] pkgs/test/release/release-attrpaths-superset.nix: init This test checks that what release-attrpaths-superset.nix calculates is in fact a superset of the attributes which are calculated by the much-slower ofborg method. To run the test, invoke this command: nix-build pkgs/test/release/release-attrpaths-superset.nix -A failures The result should be the empty list []. --- .../release/release-attrpaths-superset.nix | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 pkgs/test/release/release-attrpaths-superset.nix diff --git a/pkgs/test/release/release-attrpaths-superset.nix b/pkgs/test/release/release-attrpaths-superset.nix new file mode 100644 index 000000000000000..a5a6cb58bf826fd --- /dev/null +++ b/pkgs/test/release/release-attrpaths-superset.nix @@ -0,0 +1,74 @@ +# +# This derivation verifies that calculating the list of outpaths +# using the old slow ofborg outpaths.nix script produces exactly the +# same results as calculating them the new fast parallel way with +# the pkgs/top-level/release-outpaths-parallel.nix script. +# +# This check needs access to the shared/cached store on the CT +# runner, so it can't be executed via the migration mechanism. It +# has to wait for OfBorg to merge and deploy this PR: +# +# https://github.com/NixOS/ofborg/pull/660 +# + +{ lib ? import ../../../lib +, pkgs ? import ../../.. { } +}: +let + + nixpkgs-source = lib.cleanSource ../../..; + + attrpaths-calculated-the-ofborg-way-drv = + pkgs.runCommand "attrpaths-calculated-the-ofborg-way.txt" {} '' + cp -r ${nixpkgs-source} nixpkgs + mkdir fake-store + ${pkgs.nix}/bin/nix-env --store ./fake-store \ + -qaP \ + --no-name \ + --arg checkMeta false \ + --argstr path $(pwd)/nixpkgs \ + -f nixpkgs/pkgs/top-level/release-outpaths.nix \ + | sed 's/\.[^.]*$//' \ + | sort \ + | uniq \ + > $out + ''; + + # yes, IFD + attrpaths-calculated-the-ofborg-way = + lib.splitString "\n" + (builtins.readFile + (import attrpaths-calculated-the-ofborg-way-drv) + ); + + attrpaths-calculated-the-fast-way = + (import ../../../pkgs/top-level/release-attrpaths-superset.nix { }) + .names; + + attrset-with-every-ofborg-way-attr-set-to-true = + builtins.listToAttrs + (map (path: lib.nameValuePair path true) + attrpaths-calculated-the-ofborg-way); + + attrset-with-every-fast-way-attr-set-to-false = + builtins.listToAttrs + (map (path: lib.nameValuePair path false) + attrpaths-calculated-the-fast-way); + + attrset-should-have-no-true-attrvalues = + attrset-with-every-ofborg-way-attr-set-to-true + // attrset-with-every-fast-way-attr-set-to-false; + + failures = + lib.filter + (v: v != null) + (lib.mapAttrsToList + (k: v: if v == true then k else null) + attrset-should-have-no-true-attrvalues); + +in { + # should be [] + inherit failures; + + pass = assert failures == []; +} From d173236527fc2b4aa6058f066b3d9f43e046c71d Mon Sep 17 00:00:00 2001 From: Adam Joseph Date: Sat, 2 Dec 2023 22:26:51 -0800 Subject: [PATCH 6/6] ct/tasks.nix: run pkgs/test/release/release-attrpaths-superset.nix --- ct/tasks.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ct/tasks.nix b/ct/tasks.nix index 971d3df83af9aff..80641a99d685a05 100644 --- a/ct/tasks.nix +++ b/ct/tasks.nix @@ -34,6 +34,10 @@ let ${pkgs.nix}/bin/nix-build ./pkgs/test/release ''; + pkgs-test-release-release-attrpaths-superset ='' + ${pkgs.nix}/bin/nix-build ./pkgs/test/release/release-attrpaths-superset.nix -A pass + ''; + libtests = '' ${pkgs.nix}/bin/nix-build ./lib/tests/release.nix '';