Bundle a managed, loopback-only Navidrome sidecar with verified release preparation, native source setup, lifecycle controls, licensing, and a polished charcoal/onyx visual system

Hop-State: A_06FNDXP543RHZ4436GTD01G
Hop-Proposal: R_06FNDXNBVJNF9Q2KMKT0ASR
Hop-Task: T_06FNDRZ9CM02JWJ98SRNFNR
Hop-Attempt: AT_06FNDRZ9CNGSWJSFVV54DR8
This commit is contained in:
2026-07-12 08:34:00 -07:00
committed by Hop
parent 38b140905f
commit ed99fc7f09
22 changed files with 1661 additions and 114 deletions
+85
View File
@@ -0,0 +1,85 @@
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import { chmod, copyFile, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
const VERSION = "0.61.2";
const RELEASE_API = `https://api.github.com/repos/navidrome/navidrome/releases/tags/v${VERSION}`;
const targetTriple = execFileSync("rustc", ["--print", "host-tuple"], { encoding: "utf8" }).trim();
const archives = {
"aarch64-apple-darwin": `navidrome_${VERSION}_darwin_arm64.tar.gz`,
"x86_64-apple-darwin": `navidrome_${VERSION}_darwin_amd64.tar.gz`,
"aarch64-unknown-linux-gnu": `navidrome_${VERSION}_linux_arm64.tar.gz`,
"x86_64-unknown-linux-gnu": `navidrome_${VERSION}_linux_amd64.tar.gz`,
"x86_64-pc-windows-msvc": `navidrome_${VERSION}_windows_amd64.zip`,
};
const archiveName = archives[targetTriple];
if (!archiveName) {
throw new Error(`Navidrome ${VERSION} is not configured for Rust target ${targetTriple}.`);
}
const extension = targetTriple.includes("windows") ? ".exe" : "";
const outputDirectory = resolve("src-tauri/binaries");
const outputPath = join(outputDirectory, `navidrome-${targetTriple}${extension}`);
const resourceDirectory = resolve("src-tauri/resources");
const licensePath = join(resourceDirectory, "navidrome-LICENSE");
await mkdir(outputDirectory, { recursive: true });
await mkdir(resourceDirectory, { recursive: true });
let binaryReady = false;
let licenseReady = false;
try {
await readFile(outputPath);
binaryReady = true;
} catch {
// Download the pinned official release below when missing.
}
try {
await readFile(licensePath);
licenseReady = true;
} catch {
// Include Navidrome's GPL license in the packaged app when missing.
}
const headers = { Accept: "application/vnd.github+json", "User-Agent": "Resonant-sidecar-preparer" };
if (!licenseReady) {
const licenseResponse = await fetch(`https://raw.githubusercontent.com/navidrome/navidrome/v${VERSION}/LICENSE`, { headers });
if (!licenseResponse.ok) throw new Error(`Could not download the Navidrome license (${licenseResponse.status}).`);
await writeFile(licensePath, await licenseResponse.text());
}
if (binaryReady) {
process.stdout.write(`Navidrome ${VERSION} sidecar is ready for ${targetTriple}.\n`);
process.exit(0);
}
const releaseResponse = await fetch(RELEASE_API, { headers });
if (!releaseResponse.ok) throw new Error(`Could not read the Navidrome release metadata (${releaseResponse.status}).`);
const release = await releaseResponse.json();
const asset = release.assets.find((candidate) => candidate.name === archiveName);
if (!asset) throw new Error(`The official Navidrome release does not contain ${archiveName}.`);
const archiveResponse = await fetch(asset.browser_download_url, { headers });
if (!archiveResponse.ok) throw new Error(`Could not download ${archiveName} (${archiveResponse.status}).`);
const archive = Buffer.from(await archiveResponse.arrayBuffer());
const actualDigest = createHash("sha256").update(archive).digest("hex");
const expectedDigest = asset.digest?.replace(/^sha256:/, "");
if (!expectedDigest || actualDigest !== expectedDigest) {
throw new Error(`Checksum verification failed for ${archiveName}.`);
}
const workingDirectory = await mkdtemp(join(tmpdir(), "resonant-navidrome-"));
try {
const archivePath = join(workingDirectory, archiveName);
await writeFile(archivePath, archive);
execFileSync("tar", ["-xf", archivePath], { cwd: workingDirectory, stdio: "inherit" });
const extractedBinary = join(workingDirectory, `navidrome${extension}`);
await copyFile(extractedBinary, outputPath);
if (!extension) await chmod(outputPath, 0o755);
} finally {
await rm(workingDirectory, { recursive: true, force: true });
}
process.stdout.write(`Downloaded and verified Navidrome ${VERSION} for ${targetTriple}.\n`);