mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 14:55:43 +00:00
refactor(windows-signing): make signCommand opt-in via override config
Pinning bundle.windows.signCommand in the base tauri.conf.json broke
from-source builds: Tauri tries to invoke a signtool path that only
exists on the maintainer's machine, with a cert thumbprint they don't
have. The build-windows-check CI job already worked around this by
passing --config '{"bundle":{"windows":{"signCommand":null}}}'. If CI
needs that override, every external builder needs it too.
Invert: base config has no signCommand. Local signed builds opt in by
copying tauri.windows.signing.example.json to tauri.windows.signing.json
(gitignored), filling in local values, and running tauri:build:signed-win
which deep-merges the override via --config.
- Remove signCommand from src-tauri/tauri.conf.json
- Add src-tauri/tauri.windows.signing.example.json (template, committed)
- Gitignore src-tauri/tauri.windows.signing.json
- Add npm script tauri:build:signed-win
- Drop the --config signCommand:null workaround from build-windows-check
- Rewrite README signing section to reflect the override flow
This commit is contained in:
@@ -328,8 +328,9 @@ jobs:
|
||||
|
||||
# Compile + bundle the Windows NSIS installer on every release to catch breakage
|
||||
# (Windows-only Rust cfg, Tauri config drift, NSIS template issues). Nothing is
|
||||
# uploaded and signing is disabled — see comment on build-macos for why CI cannot
|
||||
# sign Windows. The maintainer produces and uploads the signed installer locally.
|
||||
# uploaded — see comment on build-macos for why CI cannot sign Windows. The base
|
||||
# tauri.conf.json has no signCommand, so this produces an unsigned installer
|
||||
# naturally; the maintainer signs and uploads locally via npm run tauri:build:signed-win.
|
||||
build-windows-check:
|
||||
if: ${{ inputs.build_platform_artifacts }}
|
||||
needs: create-release
|
||||
@@ -359,7 +360,7 @@ jobs:
|
||||
VITE_LASTFM_API_KEY: ${{ secrets.VITE_LASTFM_API_KEY }}
|
||||
VITE_LASTFM_API_SECRET: ${{ secrets.VITE_LASTFM_API_SECRET }}
|
||||
run: |
|
||||
npm run tauri:build -- --bundles nsis --config '{"bundle":{"windows":{"signCommand":null}}}'
|
||||
npm run tauri:build -- --bundles nsis
|
||||
|
||||
generate-manifest:
|
||||
if: ${{ inputs.build_platform_artifacts }}
|
||||
|
||||
@@ -34,6 +34,9 @@ src-tauri/target/
|
||||
src-tauri/gen/
|
||||
src-tauri/lcov.info
|
||||
|
||||
# Local Windows signing override (copy from tauri.windows.signing.example.json)
|
||||
src-tauri/tauri.windows.signing.json
|
||||
|
||||
# Frontend test coverage
|
||||
coverage/
|
||||
|
||||
|
||||
@@ -184,21 +184,27 @@ npm run tauri:build
|
||||
|
||||
## Signed Windows installer (maintainer, manual)
|
||||
|
||||
CI builds a Windows bundle on every release as a compile check, but does not sign or publish it — the Certum SimplySign Cloud OV cert requires interactive OTP login and cannot be driven from a hosted runner. The signed installer that ships in a release is therefore produced locally by the maintainer:
|
||||
CI builds a Windows bundle on every release as a compile check, but does not sign or publish it — the code-signing cert this project uses (Certum SimplySign Cloud OV) requires interactive OTP login and cannot be driven from a hosted runner. The signed installer that ships in a release is therefore produced locally by the maintainer.
|
||||
|
||||
1. Start **SimplySign Desktop** and log in (OTP via SimplySign Mobile). This makes the cloud cert available in `Cert:\CurrentUser\My`.
|
||||
2. `npm install && npm run tauri:build -- --bundles nsis`. The `--bundles nsis` flag is required — Tauri's default would also build an MSI, which rejects the `-dev` pre-release identifier. Tauri's `bundle.windows.signCommand` invokes `signtool` for the app `.exe`, every NSIS plugin DLL, and the final installer — all come out signed in one go.
|
||||
3. Verify the installer (which contains the signed app `.exe`):
|
||||
`src-tauri/tauri.conf.json` intentionally does **not** pin a `signCommand`, so a regular `npm run tauri:build` works for everyone building from source (just produces an unsigned installer). Signing is opt-in via a separate override config:
|
||||
|
||||
```powershell
|
||||
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.28000.0\x64\signtool.exe" verify /pa /v `
|
||||
"src-tauri\target\release\bundle\nsis\Psysonic_*-setup.exe"
|
||||
1. Copy `src-tauri/tauri.windows.signing.example.json` to `src-tauri/tauri.windows.signing.json` (gitignored) and fill in your local `signtool` path, timestamp URL and cert SHA1 thumbprint. The object form (`{ "cmd": ..., "args": [...] }`) is required — Tauri's string form splits on whitespace and breaks if the `signtool` path contains spaces.
|
||||
2. Make the cert available. For SimplySign, start **SimplySign Desktop** and complete OTP login so the cert shows up under `Cert:\CurrentUser\My`.
|
||||
3. Build with the override merged in:
|
||||
|
||||
```bash
|
||||
npm run tauri:build:signed-win
|
||||
```
|
||||
|
||||
Note: `src-tauri\target\release\psysonic.exe` ends up unsigned on disk — Tauri rewrites that file as a build artifact *after* signing. The signed copy is the one packed into the installer (verify by extracting the installer with 7-Zip if needed).
|
||||
4. Upload the signed `*-setup.exe` to the GitHub release.
|
||||
That's a shortcut for `npm run tauri:build -- --bundles nsis --config src-tauri/tauri.windows.signing.json`. `--bundles nsis` is required because Tauri's default would also build an MSI, which rejects the `-dev` pre-release identifier. `signtool` is invoked for the app `.exe`, every NSIS plugin DLL, and the final installer — all come out signed in one pass.
|
||||
4. Verify the signed installer:
|
||||
|
||||
The signtool path and cert thumbprint are pinned in `src-tauri/tauri.conf.json` under `bundle.windows.signCommand` (object form — required because the signtool path contains whitespace). The cert renews ~2027-04-27.
|
||||
```powershell
|
||||
signtool verify /pa /v "src-tauri\target\release\bundle\nsis\Psysonic_*-setup.exe"
|
||||
```
|
||||
|
||||
Note: `src-tauri\target\release\psysonic.exe` ends up unsigned on disk — Tauri rewrites that file as a build artifact *after* signing. The signed copy is the one packed into the installer (extract with 7-Zip if you need to verify it directly).
|
||||
5. Upload the signed `*-setup.exe` to the GitHub release.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"tauri": "tauri",
|
||||
"tauri:dev": "tauri dev",
|
||||
"tauri:build": "tauri build",
|
||||
"tauri:build:signed-win": "tauri build --bundles nsis --config src-tauri/tauri.windows.signing.json",
|
||||
"test": "vitest run && npm run check:css-imports",
|
||||
"test:watch": "vitest",
|
||||
"test:coverage": "vitest run --coverage && npm run check:css-imports"
|
||||
|
||||
@@ -68,17 +68,6 @@
|
||||
"minimumSystemVersion": "10.15"
|
||||
},
|
||||
"windows": {
|
||||
"signCommand": {
|
||||
"cmd": "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.28000.0\\x64\\signtool.exe",
|
||||
"args": [
|
||||
"sign",
|
||||
"/tr", "http://time.certum.pl",
|
||||
"/td", "sha256",
|
||||
"/fd", "sha256",
|
||||
"/sha1", "76992CED8F2236C5D674FBD8B111CD625F19269E",
|
||||
"%1"
|
||||
]
|
||||
},
|
||||
"nsis": {
|
||||
"installMode": "currentUser"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"bundle": {
|
||||
"windows": {
|
||||
"signCommand": {
|
||||
"cmd": "REPLACE_WITH_FULL_PATH_TO_SIGNTOOL_EXE",
|
||||
"args": [
|
||||
"sign",
|
||||
"/tr", "REPLACE_WITH_TIMESTAMP_URL",
|
||||
"/td", "sha256",
|
||||
"/fd", "sha256",
|
||||
"/sha1", "REPLACE_WITH_CERT_THUMBPRINT_HEX",
|
||||
"%1"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user