From d45263b5ba985675c0bf65154614363aea7c6806 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 17:53:29 +0000 Subject: [PATCH] fix(packaging): resolve bare ICU install names beside the source dylib Release run 48 failed with "ENOENT: lstat packaging/electron/libicuuc.77.dylib". Postgres.app's ICU libraries record bare install names (libicuuc.77.dylib), and the relinker passed them to realpathSync, which resolved them against the build step's working directory. Resolve a non-absolute dependency next to the image that records it, and fail with a clear message if it is not there. --- .../scripts/prepare-postgres-runtime.ts | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packaging/electron/scripts/prepare-postgres-runtime.ts b/packaging/electron/scripts/prepare-postgres-runtime.ts index 3975ade9c..f89051bd2 100644 --- a/packaging/electron/scripts/prepare-postgres-runtime.ts +++ b/packaging/electron/scripts/prepare-postgres-runtime.ts @@ -379,9 +379,23 @@ function relinkDistribution( continue; } if (dependency.startsWith("@")) continue; - let destination = mappedDestination(dependency, mappings); + // ICU's own build records bare install names such as libicuuc.77.dylib. + // Resolve those beside the source image, never against the working + // directory. + const dependencyPath = path.isAbsolute(dependency) + ? dependency + : path.resolve( + path.dirname(origins.get(filePath) ?? filePath), + dependency, + ); + if (!fs.existsSync(dependencyPath)) { + throw new Error( + `PostgreSQL dependency is missing: ${path.basename(dependency)}`, + ); + } + let destination = mappedDestination(dependencyPath, mappings); if (!destination) { - const source = fs.realpathSync(dependency); + const source = fs.realpathSync(dependencyPath); // Preserve the filename used by the Mach-O load command. Homebrew // commonly exposes a compatibility symlink such as // libicudata.78.dylib whose real file has a longer versioned name. @@ -389,7 +403,7 @@ function relinkDistribution( if (!fs.existsSync(destination)) { fs.copyFileSync(source, destination); fs.chmodSync(destination, 0o755); - origins.set(destination, dependency); + origins.set(destination, dependencyPath); if (isMachO(destination)) queue.push(destination); } copyLicenseFiles(source, licensesRoot, copiedLicenses);