Build the Windows installer in CI
The fourth leg of build-and-test.yml, in the shape of the Android one: an image workflow that builds docker/windows and pushes it tagged by the directory's tree id, and a job inside that image that lints the Windows target — the only place the cfg(windows) branches are ever compiled by CI — builds, runs the smoke tests docs/windows.md §6 specifies, packages, installs and uninstalls under Wine, and uploads the installer. Every step was run by hand in the same container first. The spec's open list closes with this: the four §3.2 items, the licence page, and the leg. What remains is what Wine cannot show, and §10 now lists it as the first real Windows run's checklist.
This commit is contained in:
@@ -22,9 +22,9 @@ permission to a package rather than after.
|
||||
| Linux | AppImage | v1 channel, **recipe not yet written** (§5) | Oldest supported glibc, and no sandbox at all |
|
||||
| Android | F-Droid | v1 channel, not yet submitted | GPLv3-clean build, reproducible, no proprietary blobs |
|
||||
| Android | Play Store | **Not v1** (§6) | Would make ARCH §6.9 binding as policy rather than as engineering |
|
||||
| Windows | NSIS per-user installer, cross-built — [windows.md](windows.md) | **Specified, not built.** Not v1 | Known folders in place of XDG; no sandbox; unsigned until there is a certificate |
|
||||
| Windows | NSIS per-user installer, cross-built — [windows.md](windows.md) | Built by CI, **untested on Windows**. Not v1 | Known folders in place of XDG; no sandbox; unsigned until there is a certificate |
|
||||
|
||||
Three of these six exist as recipes and three do not. That is stated rather than
|
||||
Four of these six exist as recipes and two do not. That is stated rather than
|
||||
smoothed over, because the value of writing the channels down is knowing which
|
||||
constraints are already being met and which are promises.
|
||||
|
||||
@@ -247,7 +247,7 @@ packaging/
|
||||
flatpak/
|
||||
paris.tourolle.darkroom.yml the manifest, and where the permissions are argued
|
||||
windows/
|
||||
darkroom.nsi specified in windows.md §5; not yet written
|
||||
darkroom.nsi the installer; docker/windows/package.sh drives it
|
||||
```
|
||||
|
||||
`packaging/` also accumulates built `.pkg.tar.zst` artefacts from local
|
||||
|
||||
+46
-28
@@ -10,11 +10,12 @@ tree has to change to compile for the target, what the installer does, how the C
|
||||
and — because there is no Windows hardware on the runner — exactly how much of the result can be
|
||||
verified before a person double-clicks it.
|
||||
|
||||
**Written as a spec; §10 is the report.** §9's steps 1, 2 and 4 have since been run —
|
||||
**Written as a spec; §10 is the report.** Every step of §9 has since been run —
|
||||
[`docker/windows/`](../docker/windows/) is the container, [`packaging/windows/darkroom.nsi`](../packaging/windows/darkroom.nsi)
|
||||
the installer, and §6's gate passes through row 4 under Wine. Four claims in the first draft were
|
||||
wrong and are corrected in place with a note; §10 lists them. Where a claim still rests on reading
|
||||
rather than running, it says so.
|
||||
the installer, [`.gitea/workflows/windows-image.yml`](../.gitea/workflows/windows-image.yml) and
|
||||
the `windows` job in `build-and-test.yml` the CI leg, and §6's gate passes through row 4 under
|
||||
Wine. Four claims in the first draft were wrong and are corrected in place with a note; §10 lists
|
||||
them. Where a claim still rests on reading rather than running, it says so.
|
||||
|
||||
---
|
||||
|
||||
@@ -146,21 +147,27 @@ in `core/` is touched, which is NFR-PORT-1 holding.
|
||||
|
||||
### 3.2 Required before the installer is worth shipping
|
||||
|
||||
Ordered by what blocks a first sign-in.
|
||||
Ordered by what blocks a first sign-in. **All four are done**; each item says how.
|
||||
|
||||
1. **Secret store.** `keyring` has a Windows Credential Manager backend; enable its feature under a
|
||||
`cfg(windows)` target dependency and add the third `impl SecretStore for PlatformSecretStore`
|
||||
beside the two that exist. The feature's exact name has changed across `keyring` majors
|
||||
(`windows-native` in 3.x) and is to be read from the 4.x changelog rather than assumed. FR-NC-2's
|
||||
rule carries over unchanged: Credential Manager is always present on Windows, so there is no
|
||||
degraded mode to state.
|
||||
1. **Secret store.** *Done.* `keyring` 4's `v1` feature set — the one the workspace already
|
||||
asks for — includes `windows-native-keyring-store`, so the Credential Manager backend needed
|
||||
no new feature name, only the crate as a `cfg(windows)` target dependency and the existing
|
||||
Secret Service implementation's `cfg` widened to include Windows. One implementation over
|
||||
both, because `keyring::Entry` is the same API over either; the only difference is that
|
||||
`is_available`'s probe always succeeds on Windows, which is correct — Credential Manager is
|
||||
always present, so FR-NC-2's degraded mode does not arise.
|
||||
|
||||
2. **Paths.** FR-PLAT-LIN-1 says XDG, and the code says it in five places by reading `XDG_*_HOME`
|
||||
and falling back to `$HOME/.local/...`. On Windows `HOME` is normally unset, so every one of
|
||||
these degrades to a relative path from the working directory — which for a Start Menu launch is
|
||||
`C:\Windows\System32`. The fix is one function per kind of directory in `dr-plat`, with the
|
||||
Windows branch reading `%APPDATA%` (config; roams) and `%LOCALAPPDATA%` (data, cache, state;
|
||||
does not), and the five call sites using it:
|
||||
2. **Paths.** *Done* — [`platform/dr-plat/src/dirs.rs`](../platform/dr-plat/src/dirs.rs). FR-PLAT-LIN-1
|
||||
says XDG, and the code said it in five places by reading `XDG_*_HOME` and falling back to
|
||||
`$HOME/.local/...`. On Windows `HOME` is normally unset, so every one of these degraded to a
|
||||
relative path from the working directory — which for a Start Menu launch is
|
||||
`C:\Windows\System32`. Now one function per kind of directory in `dr-plat`, with the Windows
|
||||
branch reading `%APPDATA%` (config; roams) and `%LOCALAPPDATA%` (data, cache, state; does
|
||||
not), and the five call sites using it. The Android overrides (`set_state_dir`,
|
||||
`set_data_dir`) stay where they were; only the fallback behind them moved. Both platforms'
|
||||
rules are unit-tested on either host, and the Windows one was confirmed by running the
|
||||
application under Wine: the log landed in `AppData\Local\darkroom\state` and nothing was
|
||||
written anywhere else.
|
||||
|
||||
| Kind | Linux today | Windows |
|
||||
|---|---|---|
|
||||
@@ -171,15 +178,18 @@ Ordered by what blocks a first sign-in.
|
||||
FR-PLAT-WIN-1 states this as the requirement. The catalog and thumbnail *formats* do not change,
|
||||
so a library directory copied from a Linux machine opens.
|
||||
|
||||
3. **Face models.** `library::system_face_models_dirs` walks `$XDG_DATA_DIRS`, which does not
|
||||
exist on Windows. The installer puts the models beside the executable (§5), so the Windows
|
||||
branch returns `current_exe().parent().join("models")`. The user-directory lookups above it are
|
||||
unchanged, so a hand-placed pair still outranks the installed one, exactly as on Linux.
|
||||
3. **Face models.** *Done.* `library::system_face_models_dirs` walked `$XDG_DATA_DIRS`, which
|
||||
does not exist on Windows. The rule moved to `dr_plat::system_data_dirs`: the installer puts
|
||||
the models beside the executable (§5), so the Windows branch returns the executable's own
|
||||
directory. The user-directory lookups above it are unchanged, so a hand-placed pair still
|
||||
outranks the installed one, exactly as on Linux.
|
||||
|
||||
4. **Opening the sign-in URL.** `launch_ui.rs` shells out to `xdg-open`. Windows wants
|
||||
`ShellExecuteW` with the `open` verb, or `cmd /C start "" <url>`; the `open` crate does the
|
||||
`cfg` for every platform and is the conventional answer. Android has its own Intent path
|
||||
already, so this is the third branch of a function that already has two.
|
||||
4. **Opening the sign-in URL.** *Done.* `launch_ui.rs` shelled out to `xdg-open`. The Windows
|
||||
branch runs `rundll32 url.dll,FileProtocolHandler <url>`, which is `ShellExecute` on the URL
|
||||
and needs no crate — chosen over `cmd /C start`, whose quoting of `&` in a query string is a
|
||||
known trap, and over the `open` crate, which would be a dependency for one line. Android has
|
||||
its own Intent path already, so this is the third branch of a function that already had two.
|
||||
*Not verified*: Wine has no browser to open.
|
||||
|
||||
5. **`std::os::unix` uses outside a `cfg`.** `diagnostics.rs` and `presets.rs` use
|
||||
`PermissionsExt` for mode bits on written files. Most are inside `#[cfg(unix)]` blocks already;
|
||||
@@ -463,6 +473,14 @@ the reasoning that produced each mistake is the thing a reader will otherwise re
|
||||
And two things it did not know to say: NSIS's default stub is 32-bit (§5.5), and `CreateShortcut`
|
||||
cannot be verified headless (§6).
|
||||
|
||||
**Still open**, in the order §3.2 gives them: the secret store, the known-folder paths, the
|
||||
models lookup beside the executable, the sign-in URL. The binary that exists today starts, and
|
||||
cannot sign in. Then §7's CI leg, whose every step has now been run by hand once.
|
||||
**Closed since**, same day: all four §3.2 items (each says how), a `LICENSE` at the repository
|
||||
root so the installer has its licence page, and §7's CI leg — `windows-image.yml` and the
|
||||
`windows` job, every step of which was run by hand in the same container first. The Windows
|
||||
target is also linted now, with `cargo clippy --target x86_64-pc-windows-gnu -- -D warnings` in
|
||||
that job, which is the only place the `cfg(windows)` branches are ever compiled by CI.
|
||||
|
||||
**What the first real Windows run has to check**, in order, because Wine cannot: that a Vulkan
|
||||
device opens on a real driver and a render completes; that fonts are found; that Credential
|
||||
Manager round-trips a sign-in and the browser opens for Login Flow v2; that the Start Menu
|
||||
shortcut exists; and that text is sharp on a scaled display (§3.3). The release notes for the
|
||||
first build should say which of these were checked and on what machine.
|
||||
|
||||
Reference in New Issue
Block a user