diff --git a/README.md b/README.md index 3e0fc586e..403b6396c 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ See [docs/cli.md](./docs/cli.md). ## Installation -Download the latest installer for your platform from the [GitHub Releases](https://github.com/EtienneLescot/openscreen/releases) page. +Every platform has a recommended route below. On Windows that is the Microsoft Store; everywhere else it is the installer from the [GitHub Releases](https://github.com/EtienneLescot/openscreen/releases) page. ### macOS @@ -93,7 +93,24 @@ After running this command, proceed to **System Settings > Privacy & Security** ### Windows -Download the `.exe` installer directly from the [Releases page](https://github.com/EtienneLescot/openscreen/releases). +**Recommended — Microsoft Store** + +[Get OpenScreen from the Microsoft Store](https://apps.microsoft.com/detail/9MXQ1HQJL5G5), or from a terminal: + +```powershell +winget install --source msstore OpenScreen +``` + +Microsoft signs the Store package during certification, so it installs with no security warning and updates itself. + +**Alternative — standalone installer** + +Download the `.exe` from the [Releases page](https://github.com/EtienneLescot/openscreen/releases). Use this if you can't reach the Store — Windows LTSC, a locked-down work machine, an offline install, or if you want a specific older version. + +> [!NOTE] +> The `.exe` is not code-signed, so Windows SmartScreen shows **"Windows protected your PC"** and reports an unknown publisher. Choose **More info** → **Run anyway** to continue. +> +> This is not a sign that something is wrong with the download: an unsigned installer earns SmartScreen's trust per file, so a brand-new build always starts out untrusted no matter how many people installed the previous one. Verifying the signature isn't an option here — there is nothing to verify. If you want the checked path, use the Store build above. If you use the `.exe`, download it only from the Releases page linked here. ### Linux diff --git a/technical-documentation/engineering/build-and-packaging.md b/technical-documentation/engineering/build-and-packaging.md index 11d8eae30..7ca6933aa 100644 --- a/technical-documentation/engineering/build-and-packaging.md +++ b/technical-documentation/engineering/build-and-packaging.md @@ -84,6 +84,22 @@ Diagnosing a suspected stale addon: serde embeds its field-name literals in the The default electron-builder target is NSIS, with an assisted installer that allows users to change the installation directory. `npm run build:win:store` explicitly selects the configured `appx` target for Microsoft Store packaging. The AppX identity, publisher, capabilities, and Store languages come from `electron-builder.json5`. Release CI builds and retains both the NSIS installer and AppX package, although the GitHub release publisher currently downloads only the `openscreen-windows` NSIS artifact. +#### Neither Windows artifact is signed + +Unlike macOS, no Windows signing is configured anywhere in the repo. Both CI artifacts come out unsigned — confirmed by `Get-AuthenticodeSignature` on the 1.8.0 build: + +| Artifact | Signature | +|---|---| +| `Openscreen.Setup.1.8.0.exe` | `NotSigned` | +| `Openscreen.Setup.1.8.0.appx` | `NotSigned` | + +That the AppX is unsigned is not a defect: Microsoft signs Store submissions during certification, and the signed copy exists only in the Store. It is never handed back, so it cannot be redistributed. Two consequences worth knowing before anyone tries to "just ship the appx instead": + +- **The AppX is not a drop-in replacement for the NSIS installer.** Windows runs an unsigned `.exe` after a SmartScreen prompt, but refuses outright to install an unsigned MSIX/AppX — sideloading requires a signature the machine already trusts. Swapping one for the other makes distribution strictly worse. +- **SmartScreen reputation is per file hash while the installer is unsigned**, so every release starts from zero and users meet the interstitial again on each new version. Signing would attach reputation to the publisher identity instead, and it would accumulate across releases. + +Buying a certificate is the fix for the `.exe`, and it stays a live option (roughly €120/year for a cloud-HSM certificate an individual can buy, since the 2023 baseline requirements forbid keeping the key in a file). It was deliberately deferred: the Store route is already signed and already paid for through the developer account, so the README recommends it first and treats the `.exe` as the documented fallback. + ### macOS > **The macOS job is currently disabled** (`if: false` in `build.yml`) because 1.8.0 ships Windows-only. That flag is release-branch-only and must not reach `main` when promoting, or every later release becomes Windows-only too. Until it is lifted, the macOS packaging path — including the compositor and ffmpeg steps described above — is exercised only by `npm run build:mac` locally. diff --git a/technical-documentation/engineering/release-and-secrets.md b/technical-documentation/engineering/release-and-secrets.md index f42cde69c..edb68d2f0 100644 --- a/technical-documentation/engineering/release-and-secrets.md +++ b/technical-documentation/engineering/release-and-secrets.md @@ -118,6 +118,10 @@ The bot token comes from a Discord application authorized with the `bot` scope. `bump-nix-package.yml` uses the workflow-scoped `GITHUB_TOKEN`; it requires repository contents and pull-request write permissions as declared in the workflow and has no additional long-lived secret. +**WinGet publishing is built but switched off.** `publish-winget.yml` gates on `vars.WINGET_IDENTIFIER != ''`, and neither that variable nor `WINGET_ACC_TOKEN` is set, so the job has reported `skipped` on every release so far — including stable ones. Nothing is broken; it has simply never run. Setting both turns it on for the next stable tag with no code change. + +Note what it would publish before turning it on: `winget-releaser` submits the **NSIS `.exe`** attached to the release to the community repository, and that installer is unsigned. Users who install through the Microsoft Store, or through `winget --source msstore`, get the Store package that Microsoft signs during certification instead. Publishing to the community source therefore adds a second, unsigned route alongside the signed one — worth doing deliberately rather than by flipping a variable. + ## Automatic `GITHUB_TOKEN` GitHub supplies `GITHUB_TOKEN` per run. Workflows use it for semantic PR validation, release-asset reads, issue bookkeeping, and the Nix bump PR. Its scopes come from each workflow's `permissions` block and it is not manually created or rotated. Do not replace it with a PAT unless cross-workflow triggering or external-repository access is actually required.