mirror of
https://github.com/NixOS/nixos-hardware
synced 2024-12-23 18:19:44 +01:00
fix ci and make it reproducible
This commit is contained in:
parent
c54cf53e02
commit
04a366f28c
5 changed files with 201 additions and 74 deletions
10
.github/workflows/test.yml
vendored
10
.github/workflows/test.yml
vendored
|
@ -7,15 +7,7 @@ on:
|
|||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
# when updating channels, also update .mergify.yml
|
||||
channel: [ nixos-unstable, nixos-24.05 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@V27
|
||||
with:
|
||||
nix_path: nixpkgs=channel:${{ matrix.channel }}
|
||||
- name: Show nixpkgs version
|
||||
run: nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version'
|
||||
- run: ./tests/run.py
|
||||
- run: nix run ./tests#run .
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ profile, pkgs }:
|
||||
{ pkgs, profile }:
|
||||
|
||||
(pkgs.nixos [
|
||||
profile
|
||||
|
|
81
tests/flake.lock
Normal file
81
tests/flake.lock
Normal file
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixos-unstable-small"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1722555600,
|
||||
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-hardware": {
|
||||
"locked": {
|
||||
"lastModified": 1723310128,
|
||||
"narHash": "sha256-IiH8jG6PpR4h9TxSGMYh+2/gQiJW9MwehFvheSb5rPc=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"rev": "c54cf53e022b0b3c1d3b8207aa0f9b194c24f0cf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixos-hardware",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1723938990,
|
||||
"narHash": "sha256-9tUadhnZQbWIiYVXH8ncfGXGvkNq3Hag4RCBEMUk7MI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "c42fcfbdfeae23e68fc520f9182dde9f38ad1890",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-unstable-small": {
|
||||
"locked": {
|
||||
"lastModified": 1723999580,
|
||||
"narHash": "sha256-mVAwJQkqcVS+BU9i2YqDz61YQt/q0KRPz8vetezs7ZE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7bae0943064987c775f857b698522ff2db2df292",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixos-stable": "nixos-stable",
|
||||
"nixos-unstable-small": "nixos-unstable-small"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
97
tests/flake.nix
Normal file
97
tests/flake.nix
Normal file
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
description = "Test flake for nixos-hardware";
|
||||
|
||||
inputs = {
|
||||
nixos-unstable-small.url = "github:NixOS/nixpkgs/nixos-unstable-small";
|
||||
nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||
# override in the test
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
flake-parts.inputs.nixpkgs-lib.follows = "nixos-unstable-small";
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs@{ flake-parts, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
systems = [
|
||||
"aarch64-linux"
|
||||
"x86_64-linux"
|
||||
"riscv64-linux"
|
||||
];
|
||||
perSystem =
|
||||
{
|
||||
system,
|
||||
lib,
|
||||
pkgs,
|
||||
inputs',
|
||||
...
|
||||
}:
|
||||
let
|
||||
blackList = [
|
||||
# does import-from-derivation
|
||||
"toshiba-swanky"
|
||||
# uses custom nixpkgs config
|
||||
"raspberry-pi-2"
|
||||
|
||||
# deprecated profiles
|
||||
"framework"
|
||||
"asus-zephyrus-ga402x"
|
||||
"lenovo-yoga-7-14ARH7"
|
||||
];
|
||||
|
||||
# There are more, but for those we need to force it.
|
||||
# In future we should probably already define it in our module.
|
||||
aarch64Systems = [
|
||||
"raspberry-pi-3"
|
||||
"raspberry-pi-4"
|
||||
"raspberry-pi-5"
|
||||
];
|
||||
|
||||
matchArch =
|
||||
moduleName:
|
||||
if builtins.elem moduleName aarch64Systems then
|
||||
pkgs.hostPlatform.system == "aarch64-linux"
|
||||
else
|
||||
# TODO also add riscv64
|
||||
pkgs.hostPlatform.system == "x86_64-linux";
|
||||
|
||||
modules = lib.filterAttrs (
|
||||
name: _: !(builtins.elem name blackList || lib.hasPrefix "common-" name) && matchArch name
|
||||
) inputs.nixos-hardware.nixosModules;
|
||||
buildProfile = import ./build-profile.nix;
|
||||
|
||||
unfreeNixpkgs =
|
||||
importPath:
|
||||
import inputs.nixos-unstable-small {
|
||||
config = {
|
||||
allowBroken = true;
|
||||
allowUnfree = true;
|
||||
nvidia.acceptLicense = true;
|
||||
};
|
||||
overlays = [ ];
|
||||
inherit system;
|
||||
};
|
||||
nixpkgsUnstable = unfreeNixpkgs inputs'.nixos-unstable-small;
|
||||
nixpkgsStable = unfreeNixpkgs inputs.nixos-stable;
|
||||
|
||||
checksForNixpkgs =
|
||||
channel: nixpkgs:
|
||||
lib.mapAttrs' (
|
||||
name: module:
|
||||
lib.nameValuePair "${channel}-${name}" (buildProfile {
|
||||
pkgs = nixpkgs;
|
||||
profile = module;
|
||||
})
|
||||
) modules;
|
||||
in
|
||||
{
|
||||
_module.args.pkgs = nixpkgsUnstable;
|
||||
checks = checksForNixpkgs "nixos-unstable" nixpkgsUnstable // checksForNixpkgs "nixos-stable" nixpkgsStable;
|
||||
packages.run = pkgs.writeShellScriptBin "run.py" ''
|
||||
#!${pkgs.bash}/bin/bash
|
||||
export PATH=${lib.makeBinPath [ pkgs.nix-eval-jobs pkgs.nix-eval-jobs.nix ]}
|
||||
exec ${pkgs.python3.interpreter} ${./.}/run.py --nixos-hardware "$@"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
85
tests/run.py
85
tests/run.py
|
@ -1,16 +1,14 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell --quiet -p nix-eval-jobs -p nix -p python3 -i python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import multiprocessing
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import IO
|
||||
|
||||
TEST_ROOT = Path(__file__).resolve().parent
|
||||
ROOT = TEST_ROOT.parent
|
||||
|
@ -22,15 +20,6 @@ RESET = "\033[0m"
|
|||
re_nixos_hardware = re.compile(r"<nixos-hardware/([^>]+)>")
|
||||
|
||||
|
||||
def parse_readme() -> list[str]:
|
||||
profiles = set()
|
||||
with ROOT.joinpath("README.md").open() as f:
|
||||
for line in f:
|
||||
if (m := re_nixos_hardware.search(line)) is not None:
|
||||
profiles.add(m.group(1).strip())
|
||||
return list(profiles)
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Run hardware tests")
|
||||
parser.add_argument(
|
||||
|
@ -45,68 +34,39 @@ def parse_args() -> argparse.Namespace:
|
|||
action="store_true",
|
||||
help="Print evaluation commands executed",
|
||||
)
|
||||
parser.add_argument("profiles", nargs="*")
|
||||
parser.add_argument(
|
||||
"--nixos-hardware",
|
||||
help="Print evaluation commands executed",
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def write_eval_test(f: IO[str], profiles: list[str]) -> None:
|
||||
build_profile = TEST_ROOT.joinpath("build-profile.nix")
|
||||
f.write(
|
||||
textwrap.dedent(
|
||||
f"""
|
||||
let
|
||||
purePkgs = system: import <nixpkgs> {{
|
||||
config = {{
|
||||
allowBroken = true;
|
||||
allowUnfree = true;
|
||||
nvidia.acceptLicense = true;
|
||||
}};
|
||||
overlays = [];
|
||||
inherit system;
|
||||
}};
|
||||
pkgs.x86_64-linux = purePkgs "x86_64-linux";
|
||||
pkgs.aarch64-linux = purePkgs "aarch64-linux";
|
||||
buildProfile = import {build_profile};
|
||||
in
|
||||
"""
|
||||
)
|
||||
)
|
||||
f.write("{\n")
|
||||
for profile in profiles:
|
||||
# does import-from-derivation
|
||||
if profile == "toshiba/swanky":
|
||||
continue
|
||||
# uses custom nixpkgs config
|
||||
if profile == "raspberry-pi/2":
|
||||
continue
|
||||
|
||||
system = "x86_64-linux"
|
||||
if profile in ("raspberry-pi/3", "raspberry-pi/4", "raspberry-pi/5"):
|
||||
system = "aarch64-linux"
|
||||
|
||||
f.write(
|
||||
f' "{profile}" = buildProfile {{ profile = import {ROOT}/{profile}; pkgs = pkgs.{system}; }};\n'
|
||||
)
|
||||
f.write("}\n")
|
||||
|
||||
|
||||
def run_eval_test(eval_test: Path, gcroot_dir: Path, jobs: int) -> list[str]:
|
||||
def run_eval_test(nixos_hardware: str, gcroot_dir: Path, jobs: int) -> list[str]:
|
||||
failed_profiles = []
|
||||
cmd = [
|
||||
"nix-eval-jobs",
|
||||
"--extra-experimental-features",
|
||||
"flakes",
|
||||
"--override-input",
|
||||
"nixos-hardware",
|
||||
nixos_hardware,
|
||||
"--gc-roots-dir",
|
||||
gcroot_dir,
|
||||
str(gcroot_dir),
|
||||
"--max-memory-size",
|
||||
"2048",
|
||||
"--workers",
|
||||
str(jobs),
|
||||
str(eval_test),
|
||||
"--flake",
|
||||
str(TEST_ROOT) + "#checks",
|
||||
"--force-recurse",
|
||||
]
|
||||
print(" ".join(map(shlex.quote,cmd)))
|
||||
proc = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
text=True,
|
||||
)
|
||||
|
||||
with proc as p:
|
||||
assert p.stdout is not None
|
||||
for line in p.stdout:
|
||||
|
@ -123,20 +83,17 @@ def run_eval_test(eval_test: Path, gcroot_dir: Path, jobs: int) -> list[str]:
|
|||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
profiles = parse_readme() if len(args.profiles) == 0 else args.profiles
|
||||
|
||||
failed_profiles = []
|
||||
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
eval_test = Path(tmpdir) / "eval-test.nix"
|
||||
gcroot_dir = Path(tmpdir) / "gcroot"
|
||||
with eval_test.open("w") as f:
|
||||
write_eval_test(f, profiles)
|
||||
failed_profiles = run_eval_test(eval_test, gcroot_dir, args.jobs)
|
||||
failed_profiles = run_eval_test(args.nixos_hardware, gcroot_dir, args.jobs)
|
||||
|
||||
if len(failed_profiles) > 0:
|
||||
print(f"\n{RED}The following {len(failed_profiles)} test(s) failed:{RESET}")
|
||||
for profile in failed_profiles:
|
||||
print(f"{sys.argv[0]} '{profile}'")
|
||||
print(f" '{profile}'")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue