fix(nix): make the sandboxed check phase pass

The flake compiled cleanly but always failed in the cargo check phase:
test binaries could not load libdbus at runtime, and a further batch of
sandbox-environment tests failed. Fix the check environment and harness
so `nix build` passes end-to-end.

- preCheck exports LD_LIBRARY_PATH (dbus/gcc libs); nixpkgs no longer
  derives it from buildInputs and autoPatchelfHook only runs at fixup
- preCheck points HOME at a writable mktemp dir (sandbox HOME is not
  writable, breaking config/secret tests)
- procps is a Linux nativeCheckInput so the fleet ps-based memory/zombie
  sampling works on NixOS
- checkPhase builds harnesses with --no-run, patches an explicit RPATH
  into the deps executables (fleet/shell tests re-exec the harness with a
  scrubbed environment), then runs tests
- RUST_TEST_THREADS=1: tests mutate process-global PATH/HOME/cwd via
  EnvVarGuard, and a concurrent shell spawn can fail to resolve the
  interpreter; serial execution makes the check deterministic
- skip two tests that cannot run in the Nix sandbox: the git-repo-root
  test needs the source tree to be a git repo, and the underwater header
  width table is calibrated against checkout git chrome

Verified with `nix build '.#packages.x86_64-linux.default'`: cli 186
passed, tui 9491 passed / 0 failed (2 filtered), auto-patchelf reports 0
unsatisfied dependencies.
This commit is contained in:
shiziku
2026-08-01 17:48:07 +08:00
parent c98648b1c0
commit f7f5559da3

View File

@@ -11,9 +11,21 @@
python3,
gitMinimal,
cacert,
procps,
rev ? "dirty",
}:
let
# Shared libraries the check-phase test binaries need at runtime
# (libdbus, libgcc_s). Derived once so LD_LIBRARY_PATH and the patchelf
# RPATH can never drift apart.
runtimeLibraryPath = lib.makeLibraryPath (
lib.optionals stdenv.isLinux [
dbus.lib
stdenv.cc.cc.lib
]
);
in
rustPlatform.buildRustPackage (finalAttrs: {
pname = "codewhale";
version = "git-${rev}";
@@ -42,6 +54,11 @@ rustPlatform.buildRustPackage (finalAttrs: {
python3
gitMinimal
cacert
]
++ lib.optionals stdenv.isLinux [
# fleet host memory/zombie sampling shells out to `ps`; NixOS has no
# system-wide /usr/bin/ps, so make it resolvable through PATH.
procps
];
cargoBuildFlags = [
@@ -53,10 +70,60 @@ rustPlatform.buildRustPackage (finalAttrs: {
cargoTestFlags = finalAttrs.cargoBuildFlags ++ [
"--lib"
"--bins"
"--"
# Requires the checkout itself to be a git repository (the test walks up
# from the current dir); the Nix source tree has no .git.
"--skip"
"tools::subagent::tests::git_repo_root_reports_attempted_paths_when_no_repo_found"
# The header width table is calibrated against the git chrome label
# populated by the surrounding checkout state, which the sandboxed test
# process does not see.
"--skip"
"tui::underwater::tests::configured_session_tokens_follow_underwater_header_width_priority"
];
preCheck = ''
# Tests write to the default config/home locations; the sandbox HOME
# (/homeless-shelter) is not writable.
export HOME="$(mktemp -d)"
export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
''
+ lib.optionalString stdenv.isLinux ''
# nixpkgs no longer derives LD_LIBRARY_PATH from buildInputs; the cargo
# test binaries link libdbus/libgcc_s dynamically and have no RPATH until
# autoPatchelfHook runs at fixup (after the check phase).
export LD_LIBRARY_PATH=${runtimeLibraryPath}
'';
# Two-stage check: build the harnesses first, give them an explicit RPATH,
# then run. Fleet and shell tests re-execute the test binary through a
# scrubbed environment (no LD_LIBRARY_PATH), so without this the re-spawned
# harness cannot load libdbus and every descendant-tree test times out.
checkPhase = ''
runHook preCheck
# Tests mutate process-global environment (PATH/HOME/cwd) via the shared
# EnvVarGuard; a concurrent test spawning a shell can then fail to resolve
# the interpreter. Run the harness serially so the check is deterministic.
export RUST_TEST_THREADS=1
flagsArray=(-j "$NIX_BUILD_CORES" --profile release --target ${stdenv.hostPlatform.config} --offline)
concatTo flagsArray cargoTestFlags checkFlags
echo "Building test binaries"
cargo test --no-run "''${flagsArray[@]}"
${lib.optionalString stdenv.isLinux ''
echo "Patching runtime RPATH into test binaries"
find "target/${stdenv.hostPlatform.config}/release/deps" \
-maxdepth 1 -type f -executable \
-exec patchelf --add-rpath "${runtimeLibraryPath}" {} +
''}
echo "Running tests"
cargo test "''${flagsArray[@]}"
runHook postCheck
'';
meta = {