Publish updates to the Gitea package registry, and build the installer on macOS
The dev machine is now a laptop, so the release path had to stop assuming Windows and a reachable network share. - tools/build-win.cjs: build the Windows x64 installer from macOS or Windows. electron-builder fetches its own mac wine build, so the only real trap is architecture: a plain `electron-builder --win` on Apple Silicon silently produces an arm64 installer the stage PC cannot run. This pins --x64 and strips the CSC_* signing vars (an EMPTY WIN_CSC_LINK aborts the build). - tools/publish-update.cjs: an http(s) destination now uploads to a Gitea generic package registry. Not a Gitea release: this server caps release attachments at 100 MB and disallows .exe, while the package registry takes the 750 MB installer and serves it anonymously — which the updater requires, since it sends no credentials. Installer first, manifest last, so a TV checking mid-publish never sees a manifest naming a file that is not there yet. - tools/release.cjs: bump, build and publish in one command. - server.js: honour "check for updates automatically when the app starts". The setting was stored but never acted on. It checks only — installing restarts the app, which must stay a deliberate tap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+99
-64
@@ -3,6 +3,16 @@
|
||||
This folder is the complete source tree of the Bible App as it runs on the stage TV (version in
|
||||
`package.json`). Everything the installer build needs is here. Nothing the build produces is.
|
||||
|
||||
The short version, once set up:
|
||||
|
||||
```bash
|
||||
npm run release -- "What changed in this version"
|
||||
git commit -am "Release <version>" && git push
|
||||
```
|
||||
|
||||
That bumps the version, builds the Windows installer, uploads it to the church Gitea server, and the
|
||||
TV picks it up from **Settings › Updates**. No .exe to hand-carry.
|
||||
|
||||
## 1. What is (and is not) in this folder
|
||||
|
||||
Included — everything the build and the app need:
|
||||
@@ -13,115 +23,140 @@ Included — everything the build and the app need:
|
||||
`dict/`, `fonts/`, `Notes/`, `Announcements/`, `Graphics/` (the defaults that ship inside the installer).
|
||||
- Vendored runtimes that ship inside the installer: `vendor/whisper`, `vendor/upscale`, `vendor/redist`,
|
||||
`vendor/llama` (the llama-server binaries — NOT the models), `vendor/fontawesome`.
|
||||
- Build inputs: `package.json`, `package-lock.json`, `build/installer.nsh`, `tools/` (`build-full-installer.cjs`,
|
||||
`publish-update.cjs`, the SFX stub in `tools/sfx`, `mock-propresenter.cjs`), `build-installer.bat`.
|
||||
- Build inputs: `package.json`, `package-lock.json`, `build/installer.nsh`, `tools/` (`build-win.cjs`,
|
||||
`release.cjs`, `publish-update.cjs`, `build-full-installer.cjs`, the SFX stub in `tools/sfx`,
|
||||
`mock-propresenter.cjs`), `build-installer.bat`.
|
||||
- The `*.md` notes at the root (small; project history worth keeping).
|
||||
|
||||
Left out on purpose (would only take space):
|
||||
|
||||
| Left out | Why |
|
||||
|---|---|
|
||||
| `dist-installer/` (57 GB), `dist/` | every old installer ever built; the build recreates them |
|
||||
| `.git/` (32 GB) | the old history had installers and models committed into it — start a fresh repo (below) |
|
||||
| `dist-installer/`, `dist/` | every installer ever built; the build recreates them |
|
||||
| `node_modules/` (640 MB) | `npm ci` recreates it exactly from `package-lock.json` |
|
||||
| `vendor/llama/*.gguf` (8 GB) | AI models; the regular installer never carries them (see §5) |
|
||||
| `.ebcache/`, `archive/`, `*.log`, `server-port.txt` | build cache, retired scratch files, runtime files |
|
||||
| `Dictionary/**/*.zip`, the Strong's XML folder | source archives; the app reads the converted JSON beside them |
|
||||
|
||||
Size of this folder: about 1.3 GB, of which ~700 MB is the vendored runtimes and ~400 MB is Bible data.
|
||||
Size of this folder: about 1.2 GB, of which ~700 MB is the vendored runtimes and ~400 MB is Bible data.
|
||||
|
||||
## 2. Build machine prerequisites (the laptop)
|
||||
## 2. Build machine prerequisites
|
||||
|
||||
- Windows 10/11 x64.
|
||||
- Node.js 22 LTS (this tree was built with Node 22.18 / npm 10.9). Install from nodejs.org.
|
||||
- Internet the first time: `npm ci` downloads Electron and electron-builder pulls NSIS and its
|
||||
winCodeSign helper into `%LOCALAPPDATA%\electron-builder\Cache` (a few hundred MB, once).
|
||||
- No code-signing certificate is used. The build must be told so (step 3).
|
||||
**The Windows installer builds on macOS as well as on Windows.** electron-builder downloads its own
|
||||
mac build of wine for the few Windows-only steps, so the laptop produces the exact same installer the
|
||||
stage PC installs. Nothing has to be done on the Windows machine any more.
|
||||
|
||||
## 3. Build the regular installer
|
||||
- macOS (Apple Silicon or Intel), or Windows 10/11 x64.
|
||||
- Node.js 22 LTS. On macOS: `brew install node@22`. On Windows: nodejs.org.
|
||||
- Internet the first time: `npm ci` downloads Electron, and electron-builder pulls NSIS, winCodeSign
|
||||
and (on macOS) wine into its cache — a few hundred MB, once.
|
||||
- No code-signing certificate is used, and `tools/build-win.cjs` sets the environment up accordingly.
|
||||
|
||||
```bat
|
||||
cd bible-app-source
|
||||
npm ci
|
||||
set CSC_IDENTITY_AUTO_DISCOVERY=false
|
||||
npx electron-builder --win
|
||||
## 3. Build the installer
|
||||
|
||||
```bash
|
||||
npm ci # first time only
|
||||
npm run build:win
|
||||
```
|
||||
|
||||
Output: `dist-installer\Bible App Setup <version>.exe` (about 750 MB).
|
||||
Output: `dist-installer/Bible App Setup <version>.exe` (about 750 MB).
|
||||
|
||||
Notes:
|
||||
|
||||
- Bump `"version"` in `package.json` before every build you intend to ship. The TV's updater compares
|
||||
versions numerically and only offers a HIGHER version.
|
||||
- `build-installer.bat` does the same as the commands above and also bumps the patch version and clears
|
||||
the electron-builder cache first. Either way works.
|
||||
- If `WIN_CSC_LINK` / `CSC_LINK` / `CSC_KEY_PASSWORD` / `CSC_KEYCHAIN` exist in your environment they must be
|
||||
REMOVED, not set to empty — electron-builder aborts on an empty `WIN_CSC_LINK`
|
||||
("Env WIN_CSC_LINK is not correct"). In PowerShell: `Remove-Item Env:WIN_CSC_LINK`.
|
||||
- If the build fails while extracting `winCodeSign` (symlink / permission errors), run the terminal as
|
||||
administrator or turn on Windows Developer Mode, delete `%LOCALAPPDATA%\electron-builder\Cache\winCodeSign`,
|
||||
and build again.
|
||||
- `npm run build:win` always builds **x64**. Do not call `npx electron-builder --win` directly on an
|
||||
Apple Silicon Mac: electron-builder defaults to the host architecture and will quietly hand you an
|
||||
arm64 build that the stage PC cannot run.
|
||||
- Bump `"version"` in `package.json` before every build you intend to ship — `npm run release` does it
|
||||
for you. The TV's updater compares versions numerically and only offers a HIGHER version.
|
||||
- If `WIN_CSC_LINK` / `CSC_LINK` / `CSC_KEY_PASSWORD` / `CSC_KEYCHAIN` exist in your environment,
|
||||
`build-win.cjs` removes them for the build (electron-builder aborts on an EMPTY `WIN_CSC_LINK`).
|
||||
- On Windows, if the build fails while extracting `winCodeSign` (symlink / permission errors), run the
|
||||
terminal as administrator or turn on Developer Mode, delete
|
||||
`%LOCALAPPDATA%\electron-builder\Cache\winCodeSign`, and build again.
|
||||
|
||||
## 4. Update the TVs remotely (no cable, no remote desktop)
|
||||
|
||||
Each TV has **Settings › Updates › "Update folder or address"** — a network share (`\\SERVER\share\bible-app`),
|
||||
a folder, or an `http://` address — plus "Check for updates automatically when the app starts". The TV reads
|
||||
`<source>/latest.json` there, compares versions, then downloads and runs the installer. The app closes,
|
||||
installs, reopens; notes, graphics, annotations and settings are kept.
|
||||
Each TV has **Settings › Updates › "Update folder or address"** plus "Check for updates automatically
|
||||
when the app starts". The TV reads `<source>/latest.json`, compares versions, then downloads and runs
|
||||
the installer. The app closes, installs, reopens; notes, graphics, annotations and settings are kept.
|
||||
|
||||
From the laptop, after a build:
|
||||
The church's update source is the Gitea **package registry**:
|
||||
|
||||
```bat
|
||||
npm run publish-update -- "\\SERVER\share\bible-app" "what changed in this version"
|
||||
```
|
||||
http://chronicles-ab.waterschurch.org:3000/api/packages/christian/generic/bible-app/latest
|
||||
```
|
||||
|
||||
That copies the newest installer into the folder and writes `latest.json` (version, file name, size,
|
||||
sha256, notes). For an `http://` source, upload the `.exe` and `latest.json` to the web server yourself.
|
||||
`npm run release` builds and publishes in one go.
|
||||
Paste that into Settings › Updates on every machine, once. It is also `bibleApp.updateTarget` in
|
||||
`package.json`, which is where the publish script gets it from.
|
||||
|
||||
The TV picks the update up at its next start (auto-check on) or when someone taps **Check for Updates**
|
||||
in Settings. It never installs without that check, so time the publish for after the service.
|
||||
> Why the package registry and not a Gitea *release*? This server caps release attachments at 100 MB
|
||||
> and does not allow `.exe`. The package registry takes the 750 MB installer and — importantly —
|
||||
> serves it to **anonymous** readers, which is what the updater needs: it sends no credentials. The
|
||||
> code repository stays private; only the published installer is readable without a login.
|
||||
|
||||
Ship a version:
|
||||
|
||||
```bash
|
||||
npm run release -- "Faster laser, new popup cards"
|
||||
```
|
||||
|
||||
That bumps the patch version, builds, uploads the installer and `latest.json`, and removes builds
|
||||
older than the previous one. To publish somewhere else instead (a network share, a folder, a web
|
||||
server), pass a destination — the same string you would put in Settings › Updates:
|
||||
|
||||
```bash
|
||||
npm run release -- --dest "\\SERVER\share\bible-app" "Notes"
|
||||
npm run publish-update -- "\\SERVER\share\bible-app" "Notes" # publish an existing build
|
||||
```
|
||||
|
||||
Publishing needs a Gitea token: `GITEA_TOKEN`, or the macOS keychain item `gitea-mcp` that the git
|
||||
tooling already uses. It is never written to disk.
|
||||
|
||||
The TV picks the update up at its next start (auto-check on) or when someone taps **Check for
|
||||
Updates** in Settings. It never installs without that check, so time the publish for after the service.
|
||||
|
||||
## 5. Full Setup (only for a brand-new machine)
|
||||
|
||||
A machine that has never had the app needs the AI model once (about 1.9 GB). That is the one-file
|
||||
"Bible App Full Setup", which drops the model into `%ProgramData%\Bible App\llama-cache` where updates never
|
||||
touch it. To build it, put the model at `vendor/llama/model.gguf` (exactly 2,019,377,696 bytes — copy it from
|
||||
the stage PC: `C:\Users\media\Downloads\bible-app\vendor\llama\model.gguf` or
|
||||
`C:\ProgramData\Bible App\llama-cache\model.gguf`; it is gitignored, so it never enters the repo), build the
|
||||
regular installer, then:
|
||||
"Bible App Full Setup", which drops the model into `%ProgramData%\Bible App\llama-cache` where updates
|
||||
never touch it. To build it, put the model at `vendor/llama/model.gguf` (exactly 2,019,377,696 bytes —
|
||||
copy it from the stage PC: `C:\ProgramData\Bible App\llama-cache\model.gguf`; it is gitignored, so it
|
||||
never enters the repo), build the regular installer, then:
|
||||
|
||||
```bat
|
||||
```bash
|
||||
node tools/build-full-installer.cjs
|
||||
```
|
||||
|
||||
Machines that already have the model keep using the regular installer.
|
||||
|
||||
## 6. Put it in git
|
||||
## 6. Git
|
||||
|
||||
```bat
|
||||
cd bible-app-source
|
||||
git init
|
||||
git add -A
|
||||
git commit -m "Bible App <version> — full source"
|
||||
git remote add origin <your local git server URL>
|
||||
git push -u origin main
|
||||
The tree lives on the church Gitea server:
|
||||
|
||||
```
|
||||
http://chronicles-ab.waterschurch.org:3000/christian/bible-app
|
||||
```
|
||||
|
||||
`.gitignore` keeps the build outputs, `node_modules`, models and logs out; `.gitattributes` stores every
|
||||
file byte-for-byte (the sources are CRLF, and several maintenance scripts match CRLF exactly).
|
||||
`git push` and `git pull` work as usual; the credential is in the macOS keychain. `.gitignore` keeps
|
||||
build outputs, `node_modules`, models and logs out; `.gitattributes` stores every file byte-for-byte
|
||||
(several maintenance scripts match CRLF exactly).
|
||||
|
||||
The first push is about 1.3 GB, mostly the vendored runtimes and Bible JSON. A local Gitea / GitLab
|
||||
handles that fine; if your server has Git LFS enabled, the commented lines in `.gitattributes` move the
|
||||
`vendor/` binaries into LFS (only do that with LFS actually on, or clones get pointer files).
|
||||
Tag what you ship, so a rollback is a checkout rather than an archaeology exercise:
|
||||
|
||||
```bash
|
||||
git tag v<version> && git push --tags
|
||||
```
|
||||
|
||||
If your server has Git LFS enabled, the commented lines in `.gitattributes` move the `vendor/`
|
||||
binaries into LFS (only do that with LFS actually on, or clones get pointer files).
|
||||
|
||||
## 7. Dev-run without building
|
||||
|
||||
```bat
|
||||
```bash
|
||||
npm ci
|
||||
node server.js
|
||||
npm start
|
||||
```
|
||||
|
||||
then open `http://localhost:8080/`. To run a test copy beside a live app, set `BIBLE_APP_PORT=8095` and
|
||||
`BIBLE_APP_DATA_DIR=<some scratch folder>` so it never touches the church's real content in
|
||||
`%APPDATA%\Bible App`.
|
||||
then open `http://localhost:8080/`. This runs the server on macOS and Windows alike. To run a test copy
|
||||
beside a live app, set `BIBLE_APP_PORT=8095` and `BIBLE_APP_DATA_DIR=<some scratch folder>` so it never
|
||||
touches the church's real content.
|
||||
|
||||
Reference in New Issue
Block a user