Files
goodbuddy/build/native-dsh-resources.cjs
T
mesalogo 4e5239256d
GoodBuddy Agents / Validate Agent source (push) Canceled after 0s
GoodBuddy Agents / Build darwin arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux x64 Agent (push) Canceled after 0s
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s
fix: keep bundled DS Web links relocatable
Preserve npm relative symlinks while preparing the desktop DS Web resources.
The previous copy rewrote CLI links to build-machine absolute paths, causing
both macOS targets to fail strict code-signature verification. The regression
runs the production preparation and builder matcher, removes the installation
and staging trees, and verifies the final link remains readable.

Recover the unpublished Desktop 0.15.0 as 0.15.1 without moving its tag.
Agent stays 0.15.0 and requires Desktop 0.15.1. Carry the unpublished notes
forward once and align the bilingual feature matrices and upgrade guidance.

Validation: complete frozen Linux tree 5372 passed, 51 skipped; Windows
packaging checks 45 passed and one POSIX-only test skipped. Typecheck, lint,
and bilingual release-note validation passed. Native macOS signing remains
an independent release check. Agent Runtime implementations are unaffected.

Release note: 修复本地 DS Web 随包依赖的链接复制,避免 macOS 安装包签名校验失败。
2026-09-28 09:51:01 +08:00

66 lines
3.8 KiB
JavaScript

const { cp, mkdir, readFile, rm } = require('node:fs/promises');
const { existsSync } = require('node:fs');
const { dirname, join, relative } = require('node:path');
const tar = require('tar');
// Preserve npm's installed layout (including nested versions) and every package
// asset. The official loader discovers plugins and browser assets at runtime.
async function prepareNativeDshResources(projectDir, platform, architecture, downloadPackage, lockedIntegrity) {
const target = join(projectDir, '.runtime-resources', `dsh-${architecture}`);
await rm(target, { recursive: true, force: true });
await mkdir(target, { recursive: true });
const visited = new Set();
function locate(name, from) {
for (let directory = from; ; directory = dirname(directory)) {
const candidate = join(directory, 'node_modules', name);
if (existsSync(join(candidate, 'package.json'))) return candidate;
if (dirname(directory) === directory) return undefined;
}
}
async function copyPackage(directory) {
if (visited.has(directory)) return;
visited.add(directory);
const manifest = JSON.parse(await readFile(join(directory, 'package.json'), 'utf8'));
await cp(directory, join(target, relative(projectDir, directory)), { recursive: true, verbatimSymlinks: true });
const optional = manifest.optionalDependencies ?? {};
for (const name of Object.keys({ ...manifest.dependencies, ...manifest.peerDependencies, ...optional })) {
const dependency = locate(name, directory);
if (dependency) await copyPackage(dependency);
else if (!(name in optional) && !manifest.peerDependenciesMeta?.[name]?.optional) {
throw new Error(`DS Web bundle is missing ${name} required by ${manifest.name}`);
}
}
}
await copyPackage(join(projectDir, 'node_modules', '@deepseek-ai', 'dsh'));
// Cross-architecture packaging cannot rely on the build host's npm optional
// selection. Fetch the exact target Sharp packages from the existing lock.
const sharp = JSON.parse(await readFile(join(projectDir, 'node_modules', 'sharp', 'package.json'), 'utf8'));
const lock = JSON.parse(await readFile(join(projectDir, 'package-lock.json'), 'utf8'));
const nativePackages = [`@img/sharp-${platform}-${architecture}`];
if (platform !== 'win32') nativePackages.push(`@img/sharp-libvips-${platform}-${architecture}`);
for (const name of nativePackages) {
const version = sharp.optionalDependencies[name];
if (!version) throw new Error(`DS Web Sharp does not support ${platform}/${architecture}`);
const destination = join(target, 'node_modules', 'sharp', 'node_modules', name);
if (existsSync(join(destination, 'package.json'))) continue;
const locked = lock.packages[`node_modules/sharp/node_modules/${name}`] ?? lock.packages[`node_modules/${name}`];
if (locked?.version !== version || !locked.integrity) throw new Error(`Missing locked ${name}@${version}`);
const integrity = locked.integrity;
const archive = await downloadPackage(projectDir, name, version, integrity);
await mkdir(destination, { recursive: true });
await tar.x({ file: archive, cwd: destination, strip: 1 });
}
const koffi = JSON.parse(await readFile(join(projectDir, 'node_modules', 'koffi', 'package.json'), 'utf8'));
const koffiName = `@koromix/koffi-${platform}-${architecture}`;
const koffiDestination = join(target, 'node_modules', koffiName);
if (!existsSync(join(koffiDestination, 'package.json'))) {
const integrity = await lockedIntegrity(projectDir, koffiName, koffi.version);
const archive = await downloadPackage(projectDir, koffiName, koffi.version, integrity);
await mkdir(koffiDestination, { recursive: true });
await tar.x({ file: archive, cwd: koffiDestination, strip: 1 });
}
return target;
}
module.exports = { prepareNativeDshResources };