From 13a7cbcd6404c6e8ef501f98a0b315da4223228c Mon Sep 17 00:00:00 2001 From: Siddharth Balyan <52913345+alt-glitch@users.noreply.github.com> Date: Tue, 5 May 2026 15:32:20 +0530 Subject: [PATCH] fix(nix): refresh stale tui npmDepsHash + fix cache-blind detection (#20144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fix-lockfiles script used 'nix build .#tui.npmDeps' to detect stale hashes. This always succeeds when the OLD derivation is cached in Cachix or cache.nixos.org — even when the source package-lock.json has changed. Fix: use prefetch-npm-deps to compute the hash directly from the lockfile and compare against what's in the nix file. Falls back to nix build only if prefetch-npm-deps fails. --- nix/lib.nix | 55 ++++++++++++++++++++++++++++++----------------------- nix/tui.nix | 2 +- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/nix/lib.nix b/nix/lib.nix index 95591eb34d..7a511c807d 100644 --- a/nix/lib.nix +++ b/nix/lib.nix @@ -163,35 +163,42 @@ for entry in "''${ENTRIES[@]}"; do IFS=":" read -r ATTR FOLDER NIX_FILE <<< "$entry" echo "==> .#$ATTR ($FOLDER -> $NIX_FILE)" - OUTPUT=$(nix build ".#$ATTR.npmDeps" --no-link --print-build-logs 2>&1) - STATUS=$? - if [ "$STATUS" -eq 0 ]; then + + # Compute the actual hash from the lockfile directly using + # prefetch-npm-deps. This avoids false "ok" from nix build when + # an old derivation is cached in a substituter (cachix/cache.nixos.org). + LOCK_FILE="$FOLDER/package-lock.json" + NEW_HASH=$(${pkgs.lib.getExe pkgs.prefetch-npm-deps} "$LOCK_FILE" 2>/dev/null) + if [ -z "$NEW_HASH" ]; then + echo " prefetch-npm-deps failed, falling back to nix build" >&2 + OUTPUT=$(nix build ".#$ATTR.npmDeps" --no-link --print-build-logs 2>&1) + STATUS=$? + if [ "$STATUS" -eq 0 ]; then + echo " ok (via nix build)" + continue + fi + NEW_HASH=$(echo "$OUTPUT" | awk '/got:/ {print $2; exit}') + if [ -z "$NEW_HASH" ]; then + if echo "$OUTPUT" | grep -qE "throttled|HTTP error 418|substituter .* is disabled|some outputs of .* are not valid"; then + echo " skipped (transient cache failure — see primary nix build for real status)" >&2 + echo "$OUTPUT" | tail -8 >&2 + continue + fi + echo " build failed with no hash mismatch:" >&2 + echo "$OUTPUT" | tail -40 >&2 + exit 1 + fi + fi + + OLD_HASH=$(grep -oE 'hash = "sha256-[^"]+"' "$NIX_FILE" | head -1 \ + | sed -E 's/hash = "(.*)"/\1/') + + if [ "$NEW_HASH" = "$OLD_HASH" ]; then echo " ok" continue fi - NEW_HASH=$(echo "$OUTPUT" | awk '/got:/ {print $2; exit}') - if [ -z "$NEW_HASH" ]; then - # Magic-Nix-Cache occasionally returns HTTP 418 / cache-throttled - # mid-run; nix then prints "outputs … not valid, so checking is - # not possible" without a `got:` line. That's an infrastructure - # blip, not a stale lockfile — warn + skip rather than failing - # the lint. A real hash mismatch would still surface in the - # primary `.#$ATTR` build, which is a separate CI job. - if echo "$OUTPUT" | grep -qE "throttled|HTTP error 418|substituter .* is disabled|some outputs of .* are not valid"; then - echo " skipped (transient cache failure — see primary nix build for real status)" >&2 - echo "$OUTPUT" | tail -8 >&2 - continue - fi - echo " build failed with no hash mismatch:" >&2 - echo "$OUTPUT" | tail -40 >&2 - exit 1 - fi - HASH_LINE=$(grep -n 'hash = "sha256-' "$NIX_FILE" | head -1 | cut -d: -f1) - OLD_HASH=$(grep -oE 'hash = "sha256-[^"]+"' "$NIX_FILE" | head -1 \ - | sed -E 's/hash = "(.*)"/\1/') - LOCK_FILE="$FOLDER/package-lock.json" echo " stale: $NIX_FILE:$HASH_LINE $OLD_HASH -> $NEW_HASH" STALE=1 diff --git a/nix/tui.nix b/nix/tui.nix index 4d27dde798..9ad63378da 100644 --- a/nix/tui.nix +++ b/nix/tui.nix @@ -4,7 +4,7 @@ let src = ../ui-tui; npmDeps = pkgs.fetchNpmDeps { inherit src; - hash = "sha256-a/HGI9OgVcTnZrMXA7xFMGnFoVxyHe95fulVz+WNYB0="; + hash = "sha256-MLcLhjTF6dgdvNBtJWzo8Nh19eNh/ZitD2b07nm61Tc="; }; npm = hermesNpmLib.mkNpmPassthru { folder = "ui-tui"; attr = "tui"; pname = "hermes-tui"; };