Unverified 提交 8fdf9d7f authored 作者: Will Chen's avatar Will Chen 提交者: GitHub

fix: skip unsupported PowerShell scripts in Windows signing (#3169)

## Summary - remove the two bundled node-pty PowerShell helper scripts before Windows signing runs - keep the Azure Trusted Signing flow unchanged for signable binaries and libraries - add a unit test covering the packaging cleanup helper ## Test plan - npm run fmt - npm run lint:fix - npm run ts - npm test Generated with Claude Code <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/dyad-sh/dyad/pull/3169" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end --> --------- Co-authored-by: 's avatarClaude <noreply@anthropic.com>
上级 fd5c9ee1
import { windowsSign } from "./windowsSign";
import { removeUnsupportedWindowsSigningFiles } from "./src/lib/windows_signing";
import type { ForgeConfig } from "@electron-forge/shared-types";
import { MakerSquirrel } from "@electron-forge/maker-squirrel";
import { MakerZIP } from "@electron-forge/maker-zip";
......@@ -74,6 +75,21 @@ if (isWindowsSigningEnabled && !process.env.AZURE_CODE_SIGNING_DLIB) {
const config: ForgeConfig = {
packagerConfig: {
windowsSign: isWindowsSigningEnabled ? windowsSign : undefined,
afterCopy: isWindowsSigningEnabled
? [
(buildPath, _electronVersion, platform, _arch, callback) => {
if (platform !== "win32") {
callback();
return;
}
removeUnsupportedWindowsSigningFiles(buildPath).then(
() => callback(),
(error) => callback(error as Error),
);
},
]
: undefined,
protocols: [
{
name: "Dyad",
......
......@@ -6,3 +6,4 @@ Read this when adding Electron native dependencies such as `node-pty`, or any pa
- Add native runtime packages to `vite.main.config.mts` `build.rollupOptions.external` so Vite does not bundle them into the main-process build.
- Add native runtime packages to `forge.config.ts` `rebuildConfig.extraModules` so Electron Forge rebuilds them against the packaged Electron version.
- If the package loads helper binaries from disk at runtime (for example `node-pty` loading `spawn-helper` or `winpty-agent` next to its native module), unpack the whole package directory with `packagerConfig.asar.unpackDir`; auto-unpacking `.node` files alone is not enough.
- Windows release builds using `@electron/windows-sign` recursively try to sign `.ps1` scripts in packaged native dependencies. If a bundled dependency includes helper PowerShell files that are not Authenticode-signable (such as `node-pty`'s `deps/winpty/misc/*.ps1`), remove or exclude them before the Forge signing step or `signtool.exe` will fail with `Number of errors: 2`.
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import {
removeUnsupportedWindowsSigningFiles,
UNSUPPORTED_WINDOWS_SIGNING_RELATIVE_PATHS,
} from "@/lib/windows_signing";
const tempDirectories: string[] = [];
afterEach(async () => {
await Promise.all(
tempDirectories
.splice(0)
.map((directory) => fs.rm(directory, { force: true, recursive: true })),
);
});
describe("removeUnsupportedWindowsSigningFiles", () => {
it("removes the node-pty PowerShell scripts that signtool cannot sign", async () => {
const buildPath = await fs.mkdtemp(
path.join(os.tmpdir(), "dyad-windows-signing-"),
);
tempDirectories.push(buildPath);
for (const relativePath of UNSUPPORTED_WINDOWS_SIGNING_RELATIVE_PATHS) {
const absolutePath = path.join(buildPath, relativePath);
await fs.mkdir(path.dirname(absolutePath), { recursive: true });
await fs.writeFile(absolutePath, "Write-Host 'hello'\n");
}
await removeUnsupportedWindowsSigningFiles(buildPath);
await Promise.all(
UNSUPPORTED_WINDOWS_SIGNING_RELATIVE_PATHS.map(async (relativePath) => {
await expect(
fs.stat(path.join(buildPath, relativePath)),
).rejects.toThrow();
}),
);
});
});
import fs from "node:fs/promises";
import path from "node:path";
export const UNSUPPORTED_WINDOWS_SIGNING_RELATIVE_PATHS = [
"node_modules/node-pty/deps/winpty/misc/ConinMode.ps1",
"node_modules/node-pty/deps/winpty/misc/IdentifyConsoleWindow.ps1",
] as const;
export async function removeUnsupportedWindowsSigningFiles(
buildPath: string,
): Promise<void> {
await Promise.all(
UNSUPPORTED_WINDOWS_SIGNING_RELATIVE_PATHS.map(async (relativePath) => {
const absolutePath = path.join(buildPath, relativePath);
await fs.rm(absolutePath, { force: true });
}),
);
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论