waffensachkunde

Waffensachkunde – Lernsoftware für die Sachkundeprüfung nach § 7 WaffG. Barrierefrei, offline, EUPL-1.2.

/ app electron-builder.yml

12,1 KB Rohdatei
app/electron-builder.yml — 263 Zeilen
1 # =====================================================================
2 # electron-builder – Paketierung für Windows (NSIS) und macOS (DMG)
3 # ---------------------------------------------------------------------
4 # CODE-SIGNIERUNG IST BEWUSST DEAKTIVIERT.
5 # Die Anwendung wird privat weitergegeben, es gibt kein Entwicklerzertifikat.
6 # Folgen, die den Nutzenden erklärt werden müssen:
7 # - Windows SmartScreen zeigt beim ersten Start „Windows hat Ihren PC
8 # geschützt“ → „Weitere Informationen“ → „Trotzdem ausführen“.
9 # - macOS Gatekeeper blockiert die App → Rechtsklick auf die App →
10 # „Öffnen“ → im Dialog erneut „Öffnen“ (bzw. Systemeinstellungen →
11 # Datenschutz & Sicherheit → „Dennoch öffnen“).
12 # =====================================================================
13
14 appId: de.willerding.waffensachkunde
15 productName: Waffensachkunde Lernsoftware
16 copyright: © 2026 Olaf Willerding
17
18 directories:
19 output: release
20 # Bewusst NICHT "build": die .gitignore im Projektwurzelverzeichnis
21 # ignoriert `build/`, dort abgelegte Icons würden also nie eingecheckt.
22 # Icons gehören nach build-resources/ (icon.ico für Windows,
23 # icon.icns bzw. icon.png >= 512x512 für macOS).
24 buildResources: build-resources
25
26 # Nur die gebauten Bundles paketieren – die Quellen bleiben draußen.
27 #
28 # ACHTUNG, DIESE LISTE STEHT DREIMAL: hier und noch einmal unter `win:` und
29 # unter `mac:`. Das ist kein Versehen, sondern der Umgang mit einer Falle von
30 # electron-builder: Eine plattformeigene `files:`-Liste ERSETZT diese hier,
31 # statt sie zu ergänzen – und besteht sie ausschließlich aus
32 # Ausschlussmustern, stellt die Bibliothek ihr `**/*` voran
33 # (`containsOnlyIgnore` in app-builder-lib/out/fileMatcher.js). Bis Fassung
34 # 0.27.2 trugen beide Plattformblöcke nur je ein `!`-Muster; das ausgelieferte
35 # `app.asar` enthielt deshalb 592 Dateien statt der fünf aus `out/`, darunter
36 # `src/`, `tests/`, `e2e/`, `tools/`, alle tsconfig-Dateien und den
37 # HTML-Abdeckungsbericht des letzten Gate-Laufs (`coverage/`, 217 Dateien,
38 # 8.967.480 Byte). `app/tests/paketstand.test.ts` hält die drei Listen
39 # deckungsgleich; `app/e2e/gepackt.spec.ts` sieht am gebauten Paket nach.
40 files:
41 - out/**/*
42 - package.json
43 - '!**/*.map'
44 - '!**/{.eslintrc,.editorconfig,.prettierrc}'
45 - '!**/{test,tests,__tests__,e2e}/**'
46 # Die C-Quellen von better-sqlite3 – die SQLite-Amalgamation und der
47 # Aufsatz darauf. Nachgemessen 9,9 MiB (deps) plus 162 KiB (src) in jedem
48 # Paket, die nie jemand ausführt: `npmRebuild: false` weiter unten schaltet
49 # den Bau aus der Quelle ab, und `lib/binding.js` lädt ausschließlich eine
50 # fertige Datei aus `prebuilds/`. Bis Fassung 0.24.1 wurden sie mitgepackt.
51 - '!**/node_modules/better-sqlite3/{deps,src}/**'
52 - '!**/node_modules/better-sqlite3/binding.gyp'
53
54 # Der amtliche Fragenkatalog liegt außerhalb von app/ und wird als Ressource
55 # mitgepackt. Ziel ist <app>/resources/katalog/ – genau dort sucht
56 # src/main/katalog.ts, wenn app.isPackaged true ist. Bewusst NICHT im
57 # asar-Archiv: so bleiben katalog.json und die Prüfzeichen normale Dateien,
58 # die mit fs gelesen werden können.
59 extraResources:
60 - from: ../content/katalog
61 to: katalog
62 filter:
63 - '**/*'
64 # Erklaerungen zu den Fragen. Eigener redaktioneller Inhalt, deshalb
65 # getrennt vom amtlichen Katalog; src/main/erklaerungen.ts sucht die
66 # Datei im gepackten Betrieb direkt unter <app>/resources/.
67 - from: ../content/erklaerungen.json
68 to: erklaerungen.json
69 # Glossar der Fachbegriffe (WCAG 3.1.3 und 3.1.4).
70 - from: ../content/glossar.json
71 to: glossar.json
72 # Die zitierten Normtexte. Ohne sie führte „Im Gesetz nachlesen" ins Leere:
73 # Eine vollständig offline arbeitende Software forderte zu etwas auf, das
74 # offline gerade nicht ging. Erzeugt aus content/gesetze/index.json mit
75 # data-pipeline/normtexte_bauen.py – und nur die zitierten Normen, denn der
76 # Index führt die sieben Gesetze vollständig, auch katalogfremde Normen.
77 # Gesetzestexte sind nach § 5 Abs. 1 UrhG gemeinfrei.
78 - from: ../content/normtexte.json
79 to: normtexte.json
80 # Die redaktionelle Feingliederung der Kapitel II bis IV. Der amtliche
81 # Katalog gliedert nur Kapitel I in Abschnitte; ohne diese Datei laesst sich
82 # von 230 Fragen nur das ganze Kapitel ueben.
83 - from: ../content/themen.json
84 to: themen.json
85 # Deutsche Fassung der EUPL 1.2 und die Übersicht der Fremdkomponenten.
86 # Beide zeigt der Bereich „Über diese Software“ an; MIT, BSD und Apache
87 # verlangen die Mitlieferung ihrer Texte. Ziel ist jeweils
88 # <app>/resources/ – genau dort sucht src/main/lizenzen.ts im gepackten
89 # Betrieb.
90 - from: ../LICENSE.de.txt
91 to: LICENSE.de.txt
92 - from: ../content/drittlizenzen.json
93 to: drittlizenzen.json
94 # Die Datenschutzerklärung, erzeugt aus docs/datenschutz.md über
95 # tools/datenschutz_anwendung.py. Bis 0.24.2 war sie in der Anwendung
96 # nirgends erreichbar: docs/ wird nicht mitgeliefert, und der einzige Weg
97 # nach außen führt zur Unterstützungsseite. src/main/datenschutz.ts sucht
98 # die Datei im gepackten Betrieb direkt unter <app>/resources/.
99 - from: ../content/datenschutz.json
100 to: datenschutz.json
101
102 # better-sqlite3 ist ein natives Modul und muss außerhalb des asar-Archivs
103 # liegen, damit der Prozess die .node-Datei laden kann.
104 asar: true
105 asarUnpack:
106 - '**/node_modules/better-sqlite3/**'
107
108 # Kein npmRebuild nötig: better-sqlite3 >= 12 liefert N-API-Prebuilds, die
109 # ABI-stabil sind und ohne Neubau unter Electron laufen.
110 npmRebuild: false
111
112 # ── Windows ──────────────────────────────────────────────────────────
113 win:
114 # Fremde Fertigteile von better-sqlite3. `lib/binding.js` setzt den
115 # Dateinamen zur Laufzeit aus `process.platform` und `process.arch`
116 # zusammen; unter Windows kann also nur `win32-*.node` je geladen werden.
117 # Die sechs anderen wiegen nachgezählt 13.003.904 Byte = 12,4 MiB (darwin
118 # arm64/x64, linux arm64/x64, linuxmusl arm64/x64). Beide
119 # Windows-Architekturen bleiben – das Ziel unten baut zwar nur x64, aber
120 # diese Liste soll nicht stillschweigend falsch werden, wenn dort arm64
121 # dazukommt.
122 #
123 # Vollständige Liste, nicht nur der Ausschluss: siehe den Hinweis über
124 # `files:` ganz oben. Was hier fehlt, wird nicht geerbt – es fehlt.
125 files:
126 - out/**/*
127 - package.json
128 - '!**/*.map'
129 - '!**/{.eslintrc,.editorconfig,.prettierrc}'
130 - '!**/{test,tests,__tests__,e2e}/**'
131 - '!**/node_modules/better-sqlite3/{deps,src}/**'
132 - '!**/node_modules/better-sqlite3/binding.gyp'
133 - '!**/node_modules/better-sqlite3/prebuilds/{darwin,linux,linuxmusl}-*.node'
134 target:
135 - target: nsis
136 arch: [x64]
137 artifactName: ${productName}-${version}-Setup-${arch}.${ext}
138 # Keine Signierung: weder Zertifikat noch Zeitstempel-Server.
139 signAndEditExecutable: true
140 signtoolOptions: null
141
142 nsis:
143 oneClick: false
144 perMachine: false
145 allowToChangeInstallationDirectory: true
146 allowElevation: true
147 createDesktopShortcut: true
148 createStartMenuShortcut: true
149 shortcutName: Waffensachkunde
150 deleteAppDataOnUninstall: false
151 # Deutschsprachiger Installer.
152 installerLanguages:
153 - de_DE
154 language: '1031' # LCID für Deutsch (Deutschland)
155
156 # ── Microsoft Store (AppX/MSIX) ──────────────────────────────────────
157 #
158 # WARUM DIESER WEG UND NICHT „EXE or MSI app“
159 # Das Partner Center bietet beides an; die einfacher aussehende Option ist
160 # die teure. Microsoft verlangt für EXE/MSI ein Installationspaket, das von
161 # einer anerkannten Zertifizierungsstelle signiert ist, das der Betreiber
162 # selbst dauerhaft hostet (versionierte Adresse je Fassung) und das still
163 # installiert — der deutschsprachige NSIS-Assistent oben wäre unzulässig.
164 # Für MSIX übernimmt Microsoft Signierung und Auslieferung kostenlos.
165 # Begründung samt Belegstellen: docs/store-eintrag.md, Abschnitt 10 Punkt 1.
166 #
167 # WARUM NICHT IM `win.target` OBEN
168 # Ein zusätzliches Ziel dort verdoppelte die Bauzeit jedes gewöhnlichen
169 # `dist:win`, und `e2e/gepackt.spec.ts` misst ohnehin `release/win-unpacked/`
170 # aus dem NSIS-Bau. Das Store-Paket entsteht deshalb über einen eigenen
171 # Aufruf: `npm run dist:store`.
172 #
173 # WERKZEUGE
174 # Keine Installation nötig. `makeappx.exe` und `makepri.exe` bringt
175 # electron-builder in seinem eigenen Werkzeugpaket mit und lädt es beim
176 # ersten Lauf.
177 appx:
178 # Die drei Werte stammen wörtlich aus dem Partner Center,
179 # Produktverwaltung → Product Identity. Erfinden geht nicht: Weichen sie
180 # ab, lehnt der Upload das Paket ab, ohne zu sagen, welcher es war.
181 identityName: O-W.Waffensachkunde-Lernsoftware-OW
182 publisher: CN=54A4AD0C-C0C3-49B6-922C-7F62CBEC7197
183 publisherDisplayName: O-W
184
185 # ACHTUNG, hier schnappt eine Falle zu: `applicationId` fällt ohne diese
186 # Zeile auf `identityName` zurück, und electron-builder prüft ihn gegen
187 # /^([A-Za-z][A-Za-z0-9]*)(\.[A-Za-z][A-Za-z0-9]*)*$/ — **keine
188 # Bindestriche**, jedes Feld muss mit einem Buchstaben beginnen. Der
189 # Identitätsname enthält drei Bindestriche und fiele durch. Deshalb steht
190 # hier ein eigener, gültiger Wert; er ist nur programmintern und erscheint
191 # nirgends für Nutzende.
192 applicationId: WaffensachkundeLernsoftware
193
194 displayName: Waffensachkunde Lernsoftware
195 # Kachelfarbe. `#1f2933` ist der dunkle Grundton der Anwendung; die
196 # Store-Kachel soll nicht heller strahlen als das Programm dahinter.
197 backgroundColor: '#1f2933'
198 languages:
199 - de-DE
200
201 # Untergrenze des Betriebssystems. Ohne diese Zeile setzt electron-builder
202 # für x64 pauschal `10.0.14316.0` (AppxTarget.js) – eine Insider-Fassung
203 # von 2016. Der Store lässt die Installation dann auf Maschinen zu, auf
204 # denen die mitgelieferte Chromium-Fassung 150 gar nicht startet: Sie
205 # verlangt **Windows 10 1809 (Build 17763)**, so wie es
206 # `docs/store-eintrag.md` 8.4 auch als Systemanforderung angibt. Der
207 # Unterschied fiele nicht beim Bauen auf, sondern beim Anwender – als
208 # Programm, das sich installieren lässt und nicht startet.
209 minVersion: 10.0.17763.0
210 # Getestet ist bislang ausschließlich unter Windows 11; die Angabe bleibt
211 # deshalb bei der Untergrenze, statt eine Erprobung zu behaupten, die es
212 # nicht gibt. Ein Durchlauf unter Windows 10 steht aus
213 # (`docs/store-eintrag.md`, Abschnitt 10 Punkt 5).
214 maxVersionTested: 10.0.17763.0
215
216 # Der Dateiname erbt sonst `win.artifactName` und hieße „…-Setup-x64.appx“.
217 # Ein Store-Paket ist kein Setup; wer beide Dateien nebeneinander liegen
218 # hat, soll sie am Namen unterscheiden können.
219 artifactName: ${productName}-${version}-Store-${arch}.${ext}
220
221 # ── macOS ────────────────────────────────────────────────────────────
222 mac:
223 # Dieselbe Rechnung wie unter Windows, gespiegelt: Unter macOS kann nur
224 # `darwin-*.node` geladen werden. Beide darwin-Fertigteile bleiben, denn
225 # das Ziel unten baut arm64 **und** x64.
226 #
227 # Vollständige Liste, nicht nur der Ausschluss: siehe den Hinweis über
228 # `files:` ganz oben.
229 files:
230 - out/**/*
231 - package.json
232 - '!**/*.map'
233 - '!**/{.eslintrc,.editorconfig,.prettierrc}'
234 - '!**/{test,tests,__tests__,e2e}/**'
235 - '!**/node_modules/better-sqlite3/{deps,src}/**'
236 - '!**/node_modules/better-sqlite3/binding.gyp'
237 - '!**/node_modules/better-sqlite3/prebuilds/{win32,linux,linuxmusl}-*.node'
238 target:
239 - target: dmg
240 arch: [arm64, x64]
241 category: public.app-category.education
242 artifactName: ${productName}-${version}-${arch}.${ext}
243 # `identity: null` schaltet die Signierung explizit ab.
244 identity: null
245 # Hardened Runtime und Notarisierung setzen eine Signierung voraus und
246 # sind deshalb ebenfalls aus.
247 hardenedRuntime: false
248 gatekeeperAssess: false
249 notarize: false
250
251 dmg:
252 artifactName: ${productName}-${version}-${arch}.${ext}
253 contents:
254 - x: 140
255 y: 200
256 type: file
257 - x: 400
258 y: 200
259 type: link
260 path: /Applications
261
262 # Keine automatischen Updates – die App wird manuell verteilt.
263 publish: null