Skip to content

Commit 114924c

Browse files
committed
fix(release): support unsigned Windows installers
1 parent 64a89c3 commit 114924c

14 files changed

Lines changed: 217 additions & 42 deletions

File tree

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
blank_issues_enabled: false
22
contact_links:
33
- name: Troubleshooting guide
4-
url: https://github.com/t41372/BrowserHistoryBackup/blob/main/TROUBLESHOOTING.md
4+
url: https://github.com/t41372/PathKeep/blob/main/TROUBLESHOOTING.md
55
about: Start here for scheduler, permissions, keyring, remote backup, and derived-state troubleshooting.
66
- name: Support guide
7-
url: https://github.com/t41372/BrowserHistoryBackup/blob/main/SUPPORT.md
7+
url: https://github.com/t41372/PathKeep/blob/main/SUPPORT.md
88
about: Read the diagnostics and redaction checklist before filing a bug.

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ on:
3232
- windows
3333
- macos
3434
unsigned_preview:
35-
description: Build unsigned preview bundles without updater artifacts
35+
description: Build unsigned bundles without updater artifacts; use this for the Windows release path.
3636
required: true
37-
default: false
37+
default: true
3838
type: boolean
3939

4040
permissions:

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ On top of that archive, PathKeep gives you powerful recall (full-text search, re
124124
Download the latest release from [GitHub Releases](https://github.com/t41372/PathKeep/releases).
125125

126126
- **macOS:** open the `.dmg`, move `PathKeep.app` to `/Applications`, then open it. Safari Browser Direct import requires granting Full Disk Access to PathKeep before scanning Safari history.
127-
- **Windows:** Support is on the way. Build from source if you want to try it out right now. ~~install the release package. Scheduled backups use Windows Task Scheduler and remain preview-quality until more machines are validated.~~
127+
- **Windows:** install the unsigned `.msi` or `-setup.exe` release package. Windows will show `Unknown Publisher`, and SmartScreen may require **More info -> Run anyway** until PathKeep has publisher reputation. Scheduled backups use Windows Task Scheduler. The installer bundles the WebView2 offline installer, but Windows Server Core / headless Server environments are not valid GUI acceptance hosts.
128128
- **Linux:** Support is on the way. Build from source if you want to try it out right now. ~~install the `.AppImage`, `.deb`, or `.rpm` artifact. Linux scheduled-backup support is still preview/manual-review because desktop keyring and `systemd --user` behavior varies by distribution.~~
129129

130130
## Uninstall
@@ -206,7 +206,7 @@ Implemented browsers appear in discovery and archive data but are not yet in the
206206
| Platform | Status | Notes |
207207
| -------- | ------- | -------------------------------------------------------------------------------------------- |
208208
| macOS | Primary | Signed / notarized builds; Touch ID session unlock; Safari support requires Full Disk Access |
209-
| Windows | Preview | MSI / NSIS builds available; code signing is maintainer-operated |
209+
| Windows | Preview | Unsigned MSI / NSIS installers; `Unknown Publisher` is expected; Task Scheduler supported |
210210
| Linux | Preview | AppImage / `.deb` / `.rpm` builds available; keyring behavior varies by desktop environment |
211211

212212
---

RELEASE.md

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This is the contributor-facing release runbook. The implementation-level source
77
| Platform | Channel | Policy |
88
| -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ |
99
| macOS | Primary | External releases should be signed and notarized before public distribution. |
10-
| Windows | Preview | CI builds installers, but maintainers must explicitly own the code-signing path they want to use. |
10+
| Windows | Preview | CI builds unsigned MSI / NSIS installers. Code signing is optional future hardening, not a release blocker. |
1111
| Linux | Preview | CI builds packages when host tooling is present; checksums are part of the release contract, signatures are not yet universal. |
1212

1313
## Browser Support Promise
@@ -18,15 +18,15 @@ This is the contributor-facing release runbook. The implementation-level source
1818

1919
## Artifact Matrix
2020

21-
| Artifact | Produced By | Audience | Notes |
22-
| ----------------------------------- | ----------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------- |
23-
| Browser bundle | `bun run build` | CI / local validation | Confirms the frontend bundle still builds. |
24-
| Debug desktop binary | `bun run desktop:build:debug` | Maintainers | Used for pre-release smoke and packaging rehearsal. |
25-
| macOS `.app` / `.dmg` | GitHub `Release` workflow | Users | Signed / notarized only when Apple secrets are configured. |
26-
| Windows installers | GitHub `Release` workflow | Users | MSI / NSIS outputs depend on the host bundle result; SmartScreen reputation depends on operator signing policy. |
27-
| Linux `.AppImage` / `.deb` / `.rpm` | GitHub `Release` workflow | Users | Requires Linux packaging dependencies on the runner. |
28-
| `SHA256SUMS.txt` | GitHub `Release` workflow | Users / operators | Attached to every release. |
29-
| `RELEASE-MANIFEST.json` | GitHub `Release` workflow | Operators / support | Lists released files, sizes, and checksums for traceability. |
21+
| Artifact | Produced By | Audience | Notes |
22+
| ----------------------------------- | ----------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
23+
| Browser bundle | `bun run build` | CI / local validation | Confirms the frontend bundle still builds. |
24+
| Debug desktop binary | `bun run desktop:build:debug` | Maintainers | Used for pre-release smoke and packaging rehearsal. |
25+
| macOS `.app` / `.dmg` | GitHub `Release` workflow | Users | Signed / notarized only when Apple secrets are configured. |
26+
| Windows installers | GitHub `Release` workflow | Users | Unsigned MSI / NSIS outputs bundle the WebView2 offline installer; `Unknown Publisher` and SmartScreen prompts are expected. |
27+
| Linux `.AppImage` / `.deb` / `.rpm` | GitHub `Release` workflow | Users | Requires Linux packaging dependencies on the runner. |
28+
| `SHA256SUMS.txt` | GitHub `Release` workflow | Users / operators | Attached to every release. |
29+
| `RELEASE-MANIFEST.json` | GitHub `Release` workflow | Operators / support | Lists released files, sizes, and checksums for traceability. |
3030

3131
## Versioning Rules
3232

@@ -83,6 +83,8 @@ Manual workflow inputs:
8383
- `draft`
8484
- `prerelease`
8585
- `release_tag` (optional explicit tag; defaults to `v<package.json version>`)
86+
- `platforms` (`all`, `linux-windows`, `linux`, `windows`, or `macos`)
87+
- `unsigned_preview` (default `true`; required for the unsigned Windows release path)
8688

8789
Workflow behavior:
8890

@@ -91,8 +93,9 @@ Workflow behavior:
9193
- generate the local size attribution bundle with `bun run release:size-audit`
9294
- resolves the tag and version up front
9395
- verifies version sync across the repo
94-
- builds release bundles on macOS, Windows, and Linux
95-
- builds updater artifacts and publishes `latest.json`
96+
- builds release bundles on the selected platform matrix
97+
- when `unsigned_preview=true`, builds unsigned bundles with `--no-sign`, disables updater artifacts, and skips `latest.json`
98+
- when `unsigned_preview=false`, builds updater artifacts and publishes `latest.json`
9699
- uploads assets to the GitHub Release
97100
- downloads the assets again
98101
- publishes `SHA256SUMS.txt`
@@ -117,7 +120,9 @@ Workflow behavior:
117120
- `TAURI_SIGNING_PRIVATE_KEY`
118121
- `TAURI_SIGNING_PRIVATE_KEY_PASSWORD`
119122

120-
The current Tauri config has `bundle.createUpdaterArtifacts=true`, so the `Release` workflow fails fast when `TAURI_SIGNING_PRIVATE_KEY` is not configured. Set the private key as a repository Actions secret before dispatching the workflow:
123+
The current Tauri config has `bundle.createUpdaterArtifacts=true`, so the `Release` workflow fails fast when `unsigned_preview=false` and `TAURI_SIGNING_PRIVATE_KEY` is not configured. Unsigned Windows installer builds use `unsigned_preview=true`; they do not need updater signing secrets and do not publish updater artifacts.
124+
125+
Set the updater private key as a repository Actions secret only before dispatching an updater-enabled release:
121126

122127
```bash
123128
gh secret set TAURI_SIGNING_PRIVATE_KEY --repo t41372/PathKeep
@@ -126,13 +131,15 @@ gh secret set TAURI_SIGNING_PRIVATE_KEY_PASSWORD --repo t41372/PathKeep
126131

127132
### Windows Signing
128133

129-
PathKeep does not hardcode a single Windows signing provider in repo config. If you want signed Windows releases, choose and wire one operator-owned path before GA:
134+
PathKeep's Windows release path is unsigned. The installer is expected to show `Unknown Publisher`, and SmartScreen may require the user to choose **More info -> Run anyway** until the project has publisher reputation.
135+
136+
The CI release config must keep Windows buildable without Windows code-signing secrets. If maintainers later want signed Windows releases, wire that as an optional hardening path without making unsigned Windows installers fail:
130137

131138
- certificate thumbprint in Tauri config
132139
- custom `signCommand`
133140
- Azure Trusted Signing / Azure Key Vault
134141

135-
Until that is configured, Windows stays an explicit preview channel.
142+
Do not gate Windows preview support on any of those providers.
136143

137144
## Platform Validation
138145

@@ -146,6 +153,7 @@ Every release rehearsal should cover:
146153
- Safari baseline backup after Full Disk Access is granted
147154
- schedule preview / install / verify / remove
148155
- Windows Task Scheduler apply / status / mismatch or not-installed / remove on a real Windows host or VM
156+
- Windows unsigned installer download, `Unknown Publisher` / SmartScreen prompt path, first launch, and reinstall / upgrade over an existing install
149157
- encrypted archive unlock and re-open
150158
- remote backup preview / execute / verify
151159
- upgrade or reinstall over existing data
@@ -179,7 +187,7 @@ If a release is bad:
179187
- Safari access on macOS still depends on Full Disk Access outside the app.
180188
- Firefox support is a history-only baseline in this release; Firefox favicons, downloads, keyword-search sidecars, and richer `moz_*` evidence remain future work.
181189
- ChatGPT Atlas / Perplexity Comet support remains scoped to the validated macOS browser-history profile layouts; Windows / Linux locations are not public release promises.
182-
- Windows SmartScreen reputation depends on maintainer signing policy and reputation, not just a successful CI build.
190+
- Windows installers are unsigned in the preview channel. SmartScreen reputation is not proof that the binary failed to build.
183191
- Linux keyring behavior varies by desktop environment; encrypted mode remains supported, but unattended unlock can degrade.
184192
- App Lock remains a session-only boundary; only macOS currently ships a real Touch ID unlock path.
185193

TESTING.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ bun run check
1212

1313
`bun run check` is the authoritative per-commit checker. It runs:
1414

15-
- `bun run check:base`: formatting, linting, i18n checks, type checking, unit tests, desktop-contract checks, Rust checks, supply-chain audit, and host-matched platform checks.
15+
- `bun run check:base`: formatting, linting, i18n checks, type checking, unit tests, desktop-contract checks, Rust checks, supply-chain audit, host-matched platform checks, and release-config drift checks.
1616
- `bun run coverage:js`: 100% statement / branch / function / line coverage for active frontend runtime source under `src/**/*.{ts,tsx}`.
1717
- `bun run coverage:rust`: 100% line + function coverage for full `src-tauri/**/src/*.rs` workspace source.
1818
- `bun run build`: TypeScript compile + Vite browser bundle.
@@ -27,6 +27,7 @@ Use these for release rehearsal and focused triage:
2727
```bash
2828
bun run verify
2929
bun run check:base
30+
bun run release:check
3031
bun run coverage:js
3132
bun run coverage:rust
3233
bun run mutation:js
@@ -45,6 +46,7 @@ bun run test:e2e:desktop-bridge
4546
What they mean:
4647

4748
- `bun run check:base`: fast static/unit/native triage path; it is not a signed-off merge gate by itself.
49+
- `bun run release:check`: focused release config guard for updater URLs, unsigned Windows installer workflow, offline WebView2 bundling, and support-link drift.
4850
- `bun run mutation:js`: desktop-contract Stryker gate used by `bun run check`.
4951
- `bun run mutation:js:full`: active frontend runtime Stryker sweep for manual / scheduled deep checks.
5052
- `bun run mutation:rust`: whole-workspace cargo-mutants deep sweep. Surviving mutants are failures unless a narrow equivalent/inapplicable exclusion is documented with evidence.
@@ -70,6 +72,7 @@ bun run test:unit:desktop-contract
7072
bun run coverage:js:desktop-contract
7173
bun run check:js
7274
bun run check:rust
75+
bun run release:check
7376
bun run mutation:js:desktop-contract
7477
bun run mutation:js:full
7578
bun run mutation:rust:quality
@@ -80,6 +83,7 @@ bun run mutation:rust:quality
8083
- Focused helpers do not replace `bun run check`.
8184
- The desktop-contract slice only protects `src/main.tsx` and `src/lib/ipc/bridge.ts`.
8285
- Browser-preview e2e does not verify native scheduler install, keyring integration, signing, notarization, or filesystem side effects. Windows Task Scheduler apply/status/remove must still be accepted on a real Windows host or VM even though the Rust unit slice uses a stubbed `schtasks` runner.
86+
- `bun run release:check` proves the release config still permits unsigned Windows installers and bundles the WebView2 offline installer; it does not prove a specific Windows host can launch the installer.
8387
- GitHub-hosted Windows runners currently validate the desktop surface with `desktop:build:debug`, `vault-platform` native-host tests, and frontend updater coverage. The `pathkeep-desktop` Rust test binary for updater/file-manager facades is skipped on Windows CI because the hosted runner fails before the test harness starts with a loader-level `STATUS_ENTRYPOINT_NOT_FOUND`; macOS/Linux still run those Rust facade tests.
8488
- Chrome desktop-bridge smoke verifies the typed desktop command facade from a real browser, but it still does not magically grant every Tauri guest API to Chrome. Treat it as an agent/dev-loop surface, not the final WebView plugin truth.
8589
- Platform validation for macOS / Windows / Linux lives in [RELEASE.md](./RELEASE.md) and [docs/plan/m4-full-polish/release-readiness-runbook.md](./docs/plan/m4-full-polish/release-readiness-runbook.md).

docs/plan/CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,3 +1248,18 @@
12481248
- 2026-05-03 closeout:`archive/history.rs` 保留 public facade、mode dispatch、baseline/lexical/fuzzy/regex SQL 與 row shaping;pagination cursor/response helpers、lazy favicon hydration、export cursor-walk/rendering 已拆到 `archive/history/{pagination,favicons,export}.rs``history.rs``1229` 行降到 `729` 行,低於 1200 行 threshold;public API 與 SQL/ranking/cursor/export/favicon precedence contract 未改。
12491249
- 同步回寫 [`docs/plan/history-read-surface-maintainability-review.md`](history-read-surface-maintainability-review.md)[`docs/architecture/module-boundary-map.md`](../architecture/module-boundary-map.md)[`docs/plan/STATUS.md`](STATUS.md)[`docs/plan/BACKLOG.md`](BACKLOG.md)[`docs/plan/CHANGELOG.md`](CHANGELOG.md)
12501250
- 驗收結果:targeted `cargo test --manifest-path src-tauri/Cargo.toml -p vault-core lexical_recall -- --test-threads=1``cargo test --manifest-path src-tauri/Cargo.toml -p vault-core archive::tests -- --test-threads=1`、Schedule Vitest regression slices、`cargo fmt --manifest-path src-tauri/Cargo.toml --all --check``git diff --check``bun run check` 通過。`bun run check` 中仍有既有 Vite `shared` chunk 超過 500 kB warning。
1251+
1252+
- [x] **WORK-RELEASE-WINDOWS-UNSIGNED-A** — Unsigned Windows Installer Release Path
1253+
- 讀先:
1254+
`README.md`
1255+
`RELEASE.md`
1256+
`TESTING.md`
1257+
`docs/plan/program/quality-matrix.md`
1258+
`.github/workflows/release.yml`
1259+
`src-tauri/tauri.conf.json`
1260+
- 目標:撤回 Windows release 必須先有 code signing 的錯誤 gate,讓 v0.2 Windows 可以透過 GitHub `Release` workflow 產出 unsigned MSI / NSIS installer。
1261+
- 契約:不引入 Windows code-signing provider、不要求 PFX / Azure Trusted Signing / certificate thumbprint、不把 Windows release support 綁到 signing secret;unsigned release 必須明確告知 `Unknown Publisher` / SmartScreen prompt;如果需要 updater artifacts,仍由 updater minisign key 另行控制,不和 Windows installer code signing 混在一起。
1262+
- 2026-05-04 closeout:Git history 已回到 `64a89c33` 乾淨基底後重做本修復;錯誤 signing-gate commit 不再作為本 work block 的基底。`Release` workflow manual dispatch 預設 `unsigned_preview=true`,Windows platform option 保留,unsigned path 透過 `--no-sign --config src-tauri/ci.unsigned.conf.json` 關閉 updater artifacts;`src-tauri/tauri.conf.json` 固定 Windows WebView2 `offlineInstaller` 並 pin WiX `upgradeCode`,避免 Windows host 缺 WebView2 runtime 時只能依賴網路 bootstrap。Updater fallback / manifest endpoint、browser-preview fallback URL 與 GitHub issue support links 全部改回 `t41372/PathKeep`
1263+
- 新增 `bun run release:check` 並納入 `check:base`,保護 PathKeep release URLs、unsigned Windows workflow、WebView2 offline installer、WiX upgrade code、support links,並防止 Windows signing gate / Azure signing script 被加回來。
1264+
- 同步回寫 [`README.md`](../../README.md)[`RELEASE.md`](../../RELEASE.md)[`TESTING.md`](../../TESTING.md)[`docs/plan/program/quality-matrix.md`](program/quality-matrix.md)[`docs/plan/STATUS.md`](STATUS.md)[`docs/plan/CHANGELOG.md`](CHANGELOG.md)
1265+
- 驗收結果:`ruby -e 'require "yaml"; YAML.load_file(".github/workflows/release.yml")'``jq empty src-tauri/tauri.conf.json package.json``node --check scripts/verify-release-config.mjs``bun run release:check``git diff --check``bun run check` 通過。

0 commit comments

Comments
 (0)