Windows: geen installer, installeren is nu omslachtig voor gebruikers #1208

Closed
opened 2026-08-04 10:54:58 +00:00 by brenno · 4 comments
Owner

Platform: Windows

Probleem
Er is geen installer voor Windows. Daardoor is het installeren omslachtig voor gebruikers.

Verwacht gedrag
Een Windows-installer (bijvoorbeeld MSI of een setup-executable) zodat gebruikers OciDeck op de gebruikelijke manier kunnen installeren, met snelkoppelingen en een nette de-installatie.

**Platform:** Windows **Probleem** Er is geen installer voor Windows. Daardoor is het installeren omslachtig voor gebruikers. **Verwacht gedrag** Een Windows-installer (bijvoorbeeld MSI of een setup-executable) zodat gebruikers OciDeck op de gebruikelijke manier kunnen installeren, met snelkoppelingen en een nette de-installatie.
Author
Owner

Uitgewerkt plan: Windows-installer (#1208)

Terecht punt: bouwen vanaf bron met Visual Studio en de vastgezette
Flutter-toolchain is zwaar voor wie de app alleen wil gebruiken. Een installer
kan — binnen strakke grenzen. Dit is het plan; er wordt nog niets gebouwd.

Uitgangspunt: een domme, offline installer

De installer verpakt uitsluitend wat make build-windows al oplevert
(build/windows/x64/runner/Release/). Hij mag:

  • de bestanden neerzetten in Program Files;
  • een snelkoppeling (Start-menu/bureaublad) maken;
  • de bestandsassociaties uit windows/file-associations.reg registreren;
  • netjes de-installeren via Programs and Features.

Wat er niet in komt, en de harde grens is: geen auto-update, geen
versiecheck, geen phone-home, geen release-feed, geen "meld nieuwe versie". Op
het moment dat de installer zichzelf wil bijwerken, botst hij met de belofte in
SECURITY.md dat OciDeck niet naar huis belt en dat een fix je bereikt door de
default branch te halen en opnieuw te bouwen. Die belofte blijft staan; de
installer is enkel gemak, geen update-kanaal.

De kernwaarden blijven overeind: decks blijven Markdown, geen lock-in, geen
account, geen server, geen telemetrie.

Techniekkeuze: Inno Setup

Voorkeur boven MSIX en WiX:

  • MSIX dwingt een pakket-identiteit en een (betaalde) store/sideload-signing
    af en zit het "gewoon een map met een exe"-model in de weg.
  • WiX kan alles maar is zwaarder in onderhoud (XML-authoring, toolchain).
  • Inno Setup geeft snelkoppeling + Programs and Features-de-installatie +
    het importeren van de bestaande .reg-sleutels met een klein, leesbaar
    script. Het .iss-script hoort in windows/, naast file-associations.reg.

Code-signing (Authenticode) — meegenomen in het ontwerp

Ondertekenen van zowel ocideck.exe als de installer, zodat SmartScreen niet
op "onbekende uitgever" slaat — voor een securitytool een slecht signaal.

  • Ondertekenen gebeurt na flutter build windows en vóór het bundelen,
    plus de installer zelf ná het bouwen (signtool of Inno's SignTool-hook).
  • Vereist een Authenticode-certificaat op naam van stichting LibreKAT (open
    besluit — zie onder). Het certificaat en zijn sleutel worden niet in de
    repo bewaard; de signing-stap leest ze uit een aparte, buiten de repo
    bewaarde bron.
  • De signing-stap is optioneel-maar-aangeraden in het script: zonder certificaat
    bouwt hij een ongetekende installer met een duidelijke waarschuwing in de
    build-uitvoer, zodat een ontwikkelaar zonder cert niet vastloopt maar wél weet
    dat het resultaat ongetekend is.

Borging zonder CI: een poort in tool/

Een installer valt structureel buiten flutter test (geen Dart-gedrag; desktop-
packaging draait niet onder de testrunner). De eerlijke borging is een poort in
tool/ (in de trant van check_bundled_docs_fresh.dart) die vasthoudt dat:

  • het .iss-script en windows/file-associations.reg niet uit elkaar lopen —
    dezelfde ProgIDs, hetzelfde ocideck.exe-pad;
  • het script de output van make build-windows verpakt en niets anders.

Zonder deze poort verrot het script stil bij de volgende hernoeming (zoals de
icon-set eerder). De feitelijke "werkt de installer" blijft een handmatige
Windows-build, want een CI-runner ontbreekt.

Documentatie en belofte

  • Eén alinea in SECURITY.md die de zin over "no signed installer" verzoent met
    het bestaan van deze installer: er is een offline installer voor gemak, hij
    update zichzelf niet, een fix komt nog steeds via rebuild.
  • Een sectie in docs/BUILD.md (die de installer op regel 428-429 al noemt):
    hoe je hem bouwt en ondertekent.

Distributie

Geen CI-runner betekent dat elke installer-build een handmatige stap op
Windows
is: make build-windows → ondertekenen → Inno Setup draaien →
installer ondertekenen → als artefact bij de release-tag hangen. Dit is de echte
terugkerende kost van "er is een installer".

Rollen die meewegen

  • Bewaker: akkoord mits dom en offline; zodra er een update-/meldkanaal in
    sluipt, wint de belofte en is het antwoord nee.
  • Jurist: een gepubliceerd binair installatie-artefact vergroot de
    zichtbaarheid als "fabrikant" onder de CRA/productaansprakelijkheid t.o.v.
    build-from-source. Geen blokkade, wel bewust te nemen vóór publicatie.
  • Informatiebeveiliger: ongetekende installer + SmartScreen ondermijnt
    vertrouwen; daarom is signing in dit ontwerp meegenomen, niet uitgesteld.

Openstaande besluiten (voor jou)

  1. Authenticode-certificaat: heeft LibreKAT er een, of moet het aangeschaft
    en beheerd worden? Zonder is het een aankoop-/sleutelbeheerbeslissing.
  2. Waar landt het installer-artefact: bij de release-tag op Forgejo, of
    elders? Er is bewust geen release-feed.

Vervolg wanneer je "bouwen" zegt

windows/ocideck.iss (Inno), tool/check_installer_sync.dart (poort),
docs/BUILD.md-sectie, SECURITY.md-alinea, en een make build-windows-installer
-doel. Bouwen en verifiëren gebeurt op een Windows-machine.

## Uitgewerkt plan: Windows-installer (#1208) Terecht punt: bouwen vanaf bron met Visual Studio en de vastgezette Flutter-toolchain is zwaar voor wie de app alleen wil gebruiken. Een installer kan — binnen strakke grenzen. Dit is het plan; er wordt nog niets gebouwd. ### Uitgangspunt: een domme, offline installer De installer verpakt uitsluitend wat `make build-windows` al oplevert (`build/windows/x64/runner/Release/`). Hij mag: - de bestanden neerzetten in Program Files; - een snelkoppeling (Start-menu/bureaublad) maken; - de bestandsassociaties uit `windows/file-associations.reg` registreren; - netjes de-installeren via *Programs and Features*. Wat er **niet** in komt, en de harde grens is: geen auto-update, geen versiecheck, geen phone-home, geen release-feed, geen "meld nieuwe versie". Op het moment dat de installer zichzelf wil bijwerken, botst hij met de belofte in `SECURITY.md` dat OciDeck niet naar huis belt en dat een fix je bereikt door de default branch te halen en opnieuw te bouwen. Die belofte blijft staan; de installer is enkel gemak, geen update-kanaal. De kernwaarden blijven overeind: decks blijven Markdown, geen lock-in, geen account, geen server, geen telemetrie. ### Techniekkeuze: Inno Setup Voorkeur boven MSIX en WiX: - **MSIX** dwingt een pakket-identiteit en een (betaalde) store/sideload-signing af en zit het "gewoon een map met een exe"-model in de weg. - **WiX** kan alles maar is zwaarder in onderhoud (XML-authoring, toolchain). - **Inno Setup** geeft snelkoppeling + `Programs and Features`-de-installatie + het importeren van de bestaande `.reg`-sleutels met een klein, leesbaar script. Het `.iss`-script hoort in `windows/`, naast `file-associations.reg`. ### Code-signing (Authenticode) — meegenomen in het ontwerp Ondertekenen van zowel `ocideck.exe` als de installer, zodat SmartScreen niet op "onbekende uitgever" slaat — voor een securitytool een slecht signaal. - Ondertekenen gebeurt **na** `flutter build windows` en **vóór** het bundelen, plus de installer zelf ná het bouwen (`signtool` of Inno's `SignTool`-hook). - Vereist een Authenticode-certificaat op naam van stichting LibreKAT (open besluit — zie onder). Het certificaat en zijn sleutel worden **niet** in de repo bewaard; de signing-stap leest ze uit een aparte, buiten de repo bewaarde bron. - De signing-stap is optioneel-maar-aangeraden in het script: zonder certificaat bouwt hij een ongetekende installer met een duidelijke waarschuwing in de build-uitvoer, zodat een ontwikkelaar zonder cert niet vastloopt maar wél weet dat het resultaat ongetekend is. ### Borging zonder CI: een poort in `tool/` Een installer valt structureel buiten `flutter test` (geen Dart-gedrag; desktop- packaging draait niet onder de testrunner). De eerlijke borging is een poort in `tool/` (in de trant van `check_bundled_docs_fresh.dart`) die vasthoudt dat: - het `.iss`-script en `windows/file-associations.reg` niet uit elkaar lopen — dezelfde ProgIDs, hetzelfde `ocideck.exe`-pad; - het script de output van `make build-windows` verpakt en niets anders. Zonder deze poort verrot het script stil bij de volgende hernoeming (zoals de icon-set eerder). De feitelijke "werkt de installer" blijft een handmatige Windows-build, want een CI-runner ontbreekt. ### Documentatie en belofte - Eén alinea in `SECURITY.md` die de zin over "no signed installer" verzoent met het bestaan van deze installer: er is een offline installer voor gemak, hij update zichzelf niet, een fix komt nog steeds via rebuild. - Een sectie in `docs/BUILD.md` (die de installer op regel 428-429 al noemt): hoe je hem bouwt en ondertekent. ### Distributie Geen CI-runner betekent dat elke installer-build een **handmatige stap op Windows** is: `make build-windows` → ondertekenen → Inno Setup draaien → installer ondertekenen → als artefact bij de release-tag hangen. Dit is de echte terugkerende kost van "er is een installer". ### Rollen die meewegen - **Bewaker**: akkoord mits dom en offline; zodra er een update-/meldkanaal in sluipt, wint de belofte en is het antwoord nee. - **Jurist**: een gepubliceerd binair installatie-artefact vergroot de zichtbaarheid als "fabrikant" onder de CRA/productaansprakelijkheid t.o.v. build-from-source. Geen blokkade, wel bewust te nemen vóór publicatie. - **Informatiebeveiliger**: ongetekende installer + SmartScreen ondermijnt vertrouwen; daarom is signing in dit ontwerp meegenomen, niet uitgesteld. ### Openstaande besluiten (voor jou) 1. **Authenticode-certificaat**: heeft LibreKAT er een, of moet het aangeschaft en beheerd worden? Zonder is het een aankoop-/sleutelbeheerbeslissing. 2. **Waar landt het installer-artefact**: bij de release-tag op Forgejo, of elders? Er is bewust geen release-feed. ### Vervolg wanneer je "bouwen" zegt `windows/ocideck.iss` (Inno), `tool/check_installer_sync.dart` (poort), `docs/BUILD.md`-sectie, `SECURITY.md`-alinea, en een `make build-windows-installer` -doel. Bouwen en verifiëren gebeurt op een Windows-machine.
Author
Owner

Besluiten (aanvulling op het plan)

1. Artefact → Forgejo. De installer hangt straks als bestand bij de
release-tag op deze tracker. Past bij "geen aparte release-feed".

2. Signing → eerst een gratis OSS-certificaat, dán bouwen. LibreKAT heeft nu
geen Authenticode-certificaat. Een ongetekende installer is afgewezen: Windows
SmartScreen toont dan "onbekende uitgever", en dat ondermijnt het vertrouwen in
uitgerekend een securitytool. In plaats daarvan eerst een gratis/goedkoop
code-signing certificaat regelen:

  • SignPath Foundation — gratis Authenticode-signing voor open-source
    projecten (aanvraag met projectverificatie).
  • Certum Open Source Code Signing — laagdrempelig, goedkoop OSS-certificaat.

Gevolg voor de planning: de installer-build is geparkeerd tot het certificaat
binnen is. De aanvraag zelf (identiteits-/projectverificatie voor de stichting)
ligt bij LibreKAT, niet in deze repo. Zodra het cert er is, volgt het bouwwerk
uit het plan hierboven: windows/ocideck.iss, tool/check_installer_sync.dart,
de docs/BUILD.md-sectie, de SECURITY.md-alinea en een
make build-windows-installer-doel, met de signing-stap erin. Bouwen en
verifiëren op een Windows-machine.

## Besluiten (aanvulling op het plan) **1. Artefact → Forgejo.** De installer hangt straks als bestand bij de release-tag op deze tracker. Past bij "geen aparte release-feed". **2. Signing → eerst een gratis OSS-certificaat, dán bouwen.** LibreKAT heeft nu geen Authenticode-certificaat. Een *ongetekende* installer is afgewezen: Windows SmartScreen toont dan "onbekende uitgever", en dat ondermijnt het vertrouwen in uitgerekend een securitytool. In plaats daarvan eerst een gratis/goedkoop code-signing certificaat regelen: - **SignPath Foundation** — gratis Authenticode-signing voor open-source projecten (aanvraag met projectverificatie). - **Certum Open Source Code Signing** — laagdrempelig, goedkoop OSS-certificaat. **Gevolg voor de planning:** de installer-build is geparkeerd tot het certificaat binnen is. De aanvraag zelf (identiteits-/projectverificatie voor de stichting) ligt bij LibreKAT, niet in deze repo. Zodra het cert er is, volgt het bouwwerk uit het plan hierboven: `windows/ocideck.iss`, `tool/check_installer_sync.dart`, de `docs/BUILD.md`-sectie, de `SECURITY.md`-alinea en een `make build-windows-installer`-doel, met de signing-stap erin. Bouwen en verifiëren op een Windows-machine.
Author
Owner

Er is een certificaat aangevraagd bij de SignPath Foundation, die dat voor open-sourceprojecten gratis doet. Op dit moment hebben we nog geen reactie op dat verzoek.

Er is een certificaat aangevraagd bij de SignPath Foundation, die dat voor open-sourceprojecten gratis doet. Op dit moment hebben we nog geen reactie op dat verzoek.
Author
Owner

Gebouwd — PR #1582 (tak feat/windows-installer)

Het uitgewerkte plan hierboven is uitgevoerd, met drie afwijkingen die het waard zijn om te noemen.

1. Plaatsing: packaging/windows/ in plaats van windows/. Het plan noemde windows/, naast file-associations.reg. Sindsdien is packaging/linux/ ontstaan (#1227) als de plek voor verpakkingsmetadata. packaging/windows/ocideck.iss spiegelt dat precedent en houdt Flutters eigen platformmap schoon.

2. Borging: een test, geen tool/-poort. Het plan vroeg om tool/check_installer_sync.dart, met als argument dat een installer buiten flutter test valt. Dat argument klopt, maar #1227 had hetzelfde probleem al opgelost met test/linux_packaging_test.dart — een offline bedradingstest. test/windows_packaging_test.dart volgt die vorm. Voordeel boven een tool/-poort: hij draait automatisch mee in de suite én staat in REGISTRATION_TESTS, dus hij bijt vóór de merge in plaats van erna. Een tweede mechanisme naast een werkend precedent leek geen winst.

3. De aanname "geen CI-runner" is onjuist. Het plan (en mijn eigen eerste versie van de documentatie) ging ervan uit dat een installer per definitie handwerk is. De forge heeft inderdaad geen Windows-machine, maar .github/workflows/release.yml op de spiegel bouwt bij elke v*-tag de Windows-zip die de forge met curl terughaalt. De installer in díe lijn hangen is dus een open besluit en geen onmogelijkheid. Dat is rechtgezet in de documentatie en krijgt een eigen issue.

Openstaande besluiten uit het plan

1. Authenticode-certificaat — uitgesteld. De ondertekening zit als schakelaar in scripts/build_windows_installer.sh: uit is de standaard en het script waarschuwt luid, aan is alles-of-niets. Het accepteert uitsluitend een vingerafdruk uit de certificaatopslag, geen sleutelbestand en geen wachtwoord, zodat ondertekenmateriaal nooit een omgevingsvariabele of runner-geheim kan worden. #1013 blijft daarmee gewoon staan.

2. Waar het artefact landt — nog open, met één voorwaarde erbij. De bewakerstoets leverde hier een botsing op die niet stilzwijgend gemaakt mag worden: een installer vraagt om verhoging, en een óngetekende installer die om verhoging vraagt leert een slechtere gewoonte aan dan een ongetekende app die je zelf uitpakt — mensen klikken installatievensters weg, en juist daar komt "Onbekende uitgever" te staan. Publiceren is dus een andere beslissing dan bouwen. De voorwaarde staat vastgelegd in docs/BUILD.md: wordt de installer gepubliceerd, dan moet hij in SHA256SUMS staan en dus onder de minisign-handtekening over dat manifest vallen. Die handtekening komt in de plaats van het afgewezen certificaat.

Wat er niet in zit

Geen bijwerken, geen versiecontrole, geen release-feed, geen netwerk — de grens die de bewaker stelde. Dat staat niet op goede bedoelingen: de poort laat de bouw vallen zodra er een downloader óf een [Code]-sectie in het script verschijnt, dat laatste omdat dáár een versiecontrole zich zou verstoppen. De alinea in SECURITY.md verzoent de belofte "geen installer die zichzelf bijwerkt" met het bestaan van deze installer.

Tot het besluit over publicatie valt, levert een release nog steeds alleen de zip. Dat staat ook zo in de changelog, zodat niemand naar een download zoekt die er niet is.

## Gebouwd — PR #1582 (tak `feat/windows-installer`) Het uitgewerkte plan hierboven is uitgevoerd, met drie afwijkingen die het waard zijn om te noemen. **1. Plaatsing: `packaging/windows/` in plaats van `windows/`.** Het plan noemde `windows/`, naast `file-associations.reg`. Sindsdien is `packaging/linux/` ontstaan (#1227) als de plek voor verpakkingsmetadata. `packaging/windows/ocideck.iss` spiegelt dat precedent en houdt Flutters eigen platformmap schoon. **2. Borging: een test, geen `tool/`-poort.** Het plan vroeg om `tool/check_installer_sync.dart`, met als argument dat een installer buiten `flutter test` valt. Dat argument klopt, maar #1227 had hetzelfde probleem al opgelost met `test/linux_packaging_test.dart` — een offline bedradingstest. `test/windows_packaging_test.dart` volgt die vorm. Voordeel boven een `tool/`-poort: hij draait automatisch mee in de suite én staat in `REGISTRATION_TESTS`, dus hij bijt vóór de merge in plaats van erna. Een tweede mechanisme naast een werkend precedent leek geen winst. **3. De aanname "geen CI-runner" is onjuist.** Het plan (en mijn eigen eerste versie van de documentatie) ging ervan uit dat een installer per definitie handwerk is. De forge heeft inderdaad geen Windows-machine, maar `.github/workflows/release.yml` op de spiegel bouwt bij elke `v*`-tag de Windows-zip die de forge met `curl` terughaalt. De installer in díe lijn hangen is dus een open besluit en geen onmogelijkheid. Dat is rechtgezet in de documentatie en krijgt een eigen issue. ## Openstaande besluiten uit het plan **1. Authenticode-certificaat — uitgesteld.** De ondertekening zit als schakelaar in `scripts/build_windows_installer.sh`: uit is de standaard en het script waarschuwt luid, aan is alles-of-niets. Het accepteert uitsluitend een vingerafdruk uit de certificaatopslag, geen sleutelbestand en geen wachtwoord, zodat ondertekenmateriaal nooit een omgevingsvariabele of runner-geheim kan worden. #1013 blijft daarmee gewoon staan. **2. Waar het artefact landt — nog open, met één voorwaarde erbij.** De bewakerstoets leverde hier een botsing op die niet stilzwijgend gemaakt mag worden: een installer vraagt om verhoging, en een óngetekende installer die om verhoging vraagt leert een slechtere gewoonte aan dan een ongetekende app die je zelf uitpakt — mensen klikken installatievensters weg, en juist daar komt "Onbekende uitgever" te staan. Publiceren is dus een andere beslissing dan bouwen. De voorwaarde staat vastgelegd in `docs/BUILD.md`: wordt de installer gepubliceerd, dan moet hij in `SHA256SUMS` staan en dus onder de minisign-handtekening over dat manifest vallen. Die handtekening komt in de plaats van het afgewezen certificaat. ## Wat er niet in zit Geen bijwerken, geen versiecontrole, geen release-feed, geen netwerk — de grens die de bewaker stelde. Dat staat niet op goede bedoelingen: de poort laat de bouw vallen zodra er een downloader óf een `[Code]`-sectie in het script verschijnt, dat laatste omdat dáár een versiecontrole zich zou verstoppen. De alinea in `SECURITY.md` verzoent de belofte "geen installer die zichzelf bijwerkt" met het bestaan van deze installer. Tot het besluit over publicatie valt, levert een release nog steeds alleen de zip. Dat staat ook zo in de changelog, zodat niemand naar een download zoekt die er niet is.
brenno 2026-08-19 17:30:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#1208
No description provided.