From ef383cb2f03d7f044ac76af381410c31996e05b8 Mon Sep 17 00:00:00 2001 From: Danny Date: Tue, 9 Jun 2026 18:20:12 +0200 Subject: [PATCH] sunken-ship: bump navidrome 0.61.2 -> 0.62.0 for inPlaylist visibility fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In navidrome 0.61.x, the inPlaylist/notInPlaylist smart-playlist criteria SQL builder did not know the smart playlist owner. It only allowed referencing PUBLIC playlists, regardless of ownership. Per the docs, an inaccessible reference makes the rule match no tracks, so notInPlaylist against a private playlist silently degrades to NOT IN () (always true) - zero filtering. Symptom: smart playlist `Unrated (de-duped)` returned 9217 tracks including all members of `[mulbo] dupe-losers` (private, same owner). GRIVINA "Я хочу" showed 3 copies (1 unique + 2 dupe-losers). Verified by DB poke: same owner_id, public=0 on both playlists. Upstream fix: navidrome/navidrome#5411 (deluan) - "Relax playlist visibility in inPlaylist/notInPlaylist rules". Passes the smart playlist owner identity into the criteria SQL builder so same-owner private references work. Shipped in v0.62.0 (2026-06-08). nixpkgs PR for this bump: NixOS/nixpkgs#529720 (tebriel), opened 2026-06-09, not yet merged. nixos-unstable still on 0.61.2. This adds a local nixos/pkgs/navidrome/ verbatim from nixpkgs master with just the 3 hash lines bumped, and wires services.navidrome.package to it. REMOVE both once nixpkgs-unstable carries 0.62.x. After deploy: smart playlist songCount 9217 -> 7101, GRIVINA dupes 3 -> 1. Confirmed via direct API fetch. Co-Authored-By: Claude Opus 4.7 (1M context) --- nixos/hosts/sunken-ship.nix | 6 ++ nixos/pkgs/navidrome/default.nix | 134 +++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 nixos/pkgs/navidrome/default.nix diff --git a/nixos/hosts/sunken-ship.nix b/nixos/hosts/sunken-ship.nix index c929d84..2614410 100644 --- a/nixos/hosts/sunken-ship.nix +++ b/nixos/hosts/sunken-ship.nix @@ -106,6 +106,12 @@ # Web UI + Substreamer client on port 4533. services.navidrome = { enable = true; + # Bumped to 0.62.0 ahead of nixpkgs (#529720) for navidrome PR + # #5411 ("Relax playlist visibility in inPlaylist/notInPlaylist + # rules"). Without this the smart playlist Unrated (de-duped) + # silently keeps dupe-losers members. Drop this line + nixos/pkgs/ + # navidrome/ when nixpkgs-unstable has 0.62.x. + package = pkgs.callPackage ../pkgs/navidrome { }; settings = { Address = "0.0.0.0"; Port = 4533; diff --git a/nixos/pkgs/navidrome/default.nix b/nixos/pkgs/navidrome/default.nix new file mode 100644 index 0000000..3f1b5db --- /dev/null +++ b/nixos/pkgs/navidrome/default.nix @@ -0,0 +1,134 @@ +# Local bump of nixpkgs navidrome (0.61.2) to 0.62.0, ahead of the +# nixpkgs PR landing. Tracks NixOS/nixpkgs#529720 (tebriel) - identical +# patch (3 lines: version + src hash + vendorHash). +# +# Why bumped: 0.62.0 ships PR navidrome/navidrome#5411, which "Relax +# playlist visibility in inPlaylist/notInPlaylist rules" - lets a smart +# playlist owner reference their own PRIVATE playlists. Without it the +# operator silently matches no tracks for private references, which +# made `Unrated (de-duped)` retain all the dupe-losers members. +# +# REMOVE this file (and the services.navidrome.package line in +# sunken-ship.nix) once nixpkgs-unstable has 0.62.x. Check: +# nix-instantiate --eval -E '(import {}).navidrome.version' +{ + buildGoModule, + buildPackages, + fetchFromGitHub, + fetchNpmDeps, + fetchpatch, + lib, + nodejs_24, + npmHooks, + pkg-config, + stdenv, + ffmpeg-headless, + taglib, + zlib, + nixosTests, + nix-update-script, + ffmpegSupport ? true, + versionCheckHook, + plugins ? [ ], +}: + +buildGoModule (finalAttrs: { + pname = "navidrome"; + version = "0.62.0"; + + src = fetchFromGitHub { + owner = "navidrome"; + repo = "navidrome"; + rev = "v${finalAttrs.version}"; + hash = "sha256-pLhb2x3dGLsCk405rBVdMwazhf0EQd72VLKtlzGoJDA="; + }; + + vendorHash = "sha256-3ciCzFhJi4YTIjGbPJ2UP8mPzQe3vBgZ+Pc7Nto1LEw="; + + npmRoot = "ui"; + + npmDeps = fetchNpmDeps { + inherit (finalAttrs) src; + sourceRoot = "${finalAttrs.src.name}/ui"; + hash = "sha256-7hy2vLCEicKzjORpJZ0mrRS8PT3GsJ8DWdvj/7SrB70="; + }; + + nativeBuildInputs = [ + buildPackages.makeWrapper + nodejs_24 + npmHooks.npmConfigHook + pkg-config + ]; + + runtimeInputs = plugins; + + overrideModAttrs = oldAttrs: { + nativeBuildInputs = lib.filter (drv: drv != npmHooks.npmConfigHook) oldAttrs.nativeBuildInputs; + preBuild = null; + }; + + buildInputs = [ + taglib + zlib + ]; + + excludedPackages = [ + "plugins" + ]; + + ldflags = [ + "-X github.com/navidrome/navidrome/consts.gitSha=${finalAttrs.src.rev}" + "-X github.com/navidrome/navidrome/consts.gitTag=v${finalAttrs.version}" + ]; + + env = lib.optionalAttrs stdenv.cc.isGNU { + CGO_CFLAGS = toString [ "-Wno-return-local-addr" ]; + }; + + postPatch = '' + patchShebangs ui/bin/update-workbox.sh + ''; + + preBuild = '' + make buildjs + ''; + + postInstall = '' + mkdir -p $out/share/plugins/ + ${lib.concatMapStringsSep "\n" (plugin: '' + ln -s ${plugin}/share/${plugin.pname}.ndp $out/share/plugins/ + '') plugins} + ''; + + tags = [ + "netgo" + "sqlite_fts5" + ]; + + nativeInstallCheckInputs = [ versionCheckHook ]; + doInstallCheck = true; + + postFixup = lib.optionalString ffmpegSupport '' + wrapProgram $out/bin/navidrome \ + --prefix PATH : ${lib.makeBinPath [ ffmpeg-headless ]} + ''; + + passthru = { + inherit plugins; + tests.navidrome = nixosTests.navidrome; + updateScript = nix-update-script { }; + }; + + meta = { + description = "Music Server and Streamer compatible with Subsonic/Airsonic"; + mainProgram = "navidrome"; + homepage = "https://www.navidrome.org/"; + license = lib.licenses.gpl3Only; + sourceProvenance = with lib.sourceTypes; [ fromSource ]; + maintainers = with lib.maintainers; [ + aciceri + tebriel + ]; + broken = stdenv.hostPlatform.isDarwin; + }; +})