Signing with hooks in Squirrel maker results in wrong sign tool being used
- Dominant language
- TypeScript
- Stars
- 7.1k
- Forks
- 641
- Avg merge
- 3d 1h
- Merged PRs (30d)
- 30
Description
### Pre-flight checklist
- [X] I have read the [contribution documentation](https://github.com/electron/forge/blob/main/CONTRIBUTING.md) for this project.
- [X] I agree to follow the [code of conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project uses.
- [X] I have searched the issue tracker for a bug that matches the one I want to file, without success.
### Electron Forge version
7.4.0
### Electron version
29.1.0
### Operating system
Ubuntu 22.04.4 LTS (WSL)
### Last known working Electron Forge version
_No response_
### Expected behavior
When providing custom hook module to the Squirrel maker under winSign config, it should use the custom logic and not the `signtool.exe`.
### Actual behavior
When providing custom hook module to the Squirrel maker under winSign config, it attempts to use `signtool.exe`.
### Steps to reproduce
1. Setup basic ElectronJS app with all defaults (skeleton app will do fine).
2. Add Squirrel maker configuration such as that provided below.
3. Add custom code signing logic (see below for js files but could just be as simple as console.log).
4. Attempt to publish package.
As you can see in the build log, the packager configuration for this works well and picks up the hook:
```
2024-08-30T20:18:02.600Z electron-packager Running @electron/windows-sign with the options {"debug":true,"hookModulePath":"/__w/opa/opa/packages/file-signing/dist/index.js","appDirectory":"/__w/opa/opa/apps/.tmp/electron-packager/tmp-UEJqzL"}
2024-08-30T20:18:02.601Z electron-windows-sign Called with options {
options: {
debug: true,
hookModulePath: '/__w/opa/opa/packages/file-signing/dist/index.js',
appDirectory: '/__w/opa/opa/apps/.tmp/electron-packager/tmp-UEJqzL'
}
}
2024-08-30T20:18:02.604Z electron-windows-sign Signing with hook
```
This results in signed executables, ddls etc being generated for the application. However, when trying to sign the installer with the Squirrel maker, it does not use that hook:
```
❯ Making a squirrel distributable for win32/x64
2024-08-30T20:19:07.363Z electron-windows-sign Calling /usr/local/bin/node with options: [ '--experimental-sea-config', 'sea-config.json' ]
2024-08-30T20:19:07.370Z electron-windows-sign Spawning /usr/local/bin/node with --experimental-sea-config,sea-config.json
2024-08-30T20:19:07.377Z electron-windows-sign Spawn /usr/local/bin/node stderr: Wrote single executable preparation blob to sea.blob
2024-08-30T20:19:07.380Z electron-windows-sign Spawn /usr/local/bin/node: Child process exited with code 0
2024-08-30T20:19:07.380Z electron-windows-sign stdout:
2024-08-30T20:19:07.380Z electron-windows-sign stderr: Wrote single executable preparation blob to sea.blob
2024-08-30T20:19:07.380Z electron-windows-sign Creating signtool.exe in /__w/opa/opa/node_modules/electron-winstaller/vendor
2024-08-30T20:19:07.519Z electron-windows-sign Spawning /__w/opa/opa/node_modules/@electron/windows-sign/vendor/signtool.exe with remove,/s,/__w/opa/opa/node_modules/electron-winstaller/vendor/signtool.exe
An unhandled exception has occurred inside Forge:
spawn /__w/opa/opa/node_modules/@electron/windows-sign/vendor/signtool.exe EACCES
Error: spawn /__w/opa/opa/node_modules/@electron/windows-sign/vendor/signtool.exe EACCES
at Process.ChildProcess._handle.onexit (node:internal/child_process:286:19)
at onErrorNT (node:internal/child_process:484:16)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: "publish" exited with 1.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed.
Exit code: 1
```
I'm struggling to debug this but it looks like the wrong options are being passed from the Squirrel maker to the windows signing.
I also looked for hooks so I could do something there but that didn't work either. The goal here is to sign the installer before uploading through the S3 publisher.
### Additional information
**Custom Signing Logic:** [dist.zip](https://github.com/user-attachments/files/16821930/dist.zip)
**Build Log:** [buildlog.txt](https://github.com/user-attachments/files/16821964/buildlog.txt)
**forge.config.ts**
```
import path from "path";
import type { ForgeConfig } from "@electron-forge/shared-types";
import { MakerSquirrel } from "@electron-forge/maker-squirrel";
import { AutoUnpackNativesPlugin } from "@electron-forge/plugin-auto-unpack-natives";
import { WebpackPlugin } from "@electron-forge/plugin-webpack";
import { FusesPlugin } from "@electron-forge/plugin-fuses";
import { FuseV1Options, FuseVersion } from "@electron/fuses";
import { mainConfig } from "./webpack.main.config";
import { rendererConfig } from "./webpack.renderer.config";
import { AUTO_UPDATER_FEED_URL, AUTO_UPDATER_BUCKET_NAME, ICO_URL } from "./src/_constants";
const basePath = (fileName: string) => path.join(process.cwd(), "resources", fileName);
const srcPath = (fileName: string) => path.join(process.cwd(), "src", fileName);
const config: ForgeConfig = {
packagerConfig: {
asar: true,
icon: basePath("appicon.ico"),
extraResource: [basePath("appicon.ico")],
tmpdir: path.join(__dirname, "..", ".tmp"),
overwrite: true,
windowsSign: {
debug: true,
hookModulePath: path.join(__dirname, "../../packages/file-signing/dist/index.js"),
}
},
rebuildConfig: {},
makers: [
new MakerSquirrel({
name: "ApplicationName",
...(process.env.NO_REMOTE_RELEASES ? {} : { remoteReleases: AUTO_UPDATER_FEED_URL }),
iconUrl: ICO_URL,
loadingGif: basePath("appsplash.gif"),
setupIcon: basePath("appicon.ico"),
windowsSign: {
debug: true,
hookModulePath: path.join(__dirname, "../../packages/file-signing/dist/index.js"),
}
}),
],
publishers: [
{
name: "@electron-forge/publisher-s3",
config: {
bucket: AUTO_UPDATER_BUCKET_NAME,
},
},
],
plugins: [
new AutoUnpackNativesPlugin({}),
new WebpackPlugin({
mainConfig,
renderer: {
config: rendererConfig,
entryPoints: [
{
html: srcPath("index.html"),
js: srcPath("renderer.ts"),
name: "main_window",
preload: {
js: srcPath("preload.ts"),
},
},
],
},
}),
// Fuses are used to enable/disable various Electron functionality
// at package time, before code signing the application
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true,
}),
],
};
export default config;
```
Worth noting that I have also tried setting the maker config as the below which did not work either:
```
{
name: "@electron-forge/maker-squirrel",
config: {
name: "GlobalAccessPaxtonNet2",
...(process.env.NO_REMOTE_RELEASES ? {} : { remoteReleases: AUTO_UPDATER_FEED_URL }),
iconUrl: ICO_URL,
loadingGif: basePath("appicon.gif"),
setupIcon: basePath("appicon.ico"),
windowsSign: {
debug: true,
hookModulePath: path.join(__dirname, "../../packages/file-signing/dist/index.js"),
}
},
},
```
Contributor guide
Assessment
This issue has not been assessed yet.