Files
bible-app/BUILD-AND-DEPLOY.md
T
christianandClaude Opus 5 838a87dbf3 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>
2026-09-24 13:17:55 -04:00

7.5 KiB
Raw Blame History

Bible App — build on the laptop, push to git, update the TVs remotely

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:

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:

  • All sources: app.js, server.js, main.cjs, preload.cjs, init.js, the *.html pages, styles.css, every additive module (follower-*.js, tool-wheel.js, propresenter-*.js, quick-dock.js, …).
  • App data: Translations/, the *_bible.json files, nlt-data.js, interlinear/, Dictionary/ (JSON), 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-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/, 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.2 GB, of which ~700 MB is the vendored runtimes and ~400 MB is Bible data.

2. Build machine prerequisites

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.

  • 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.

3. Build the installer

npm ci          # first time only
npm run build:win

Output: dist-installer/Bible App Setup <version>.exe (about 750 MB).

Notes:

  • 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" 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.

The church's update source is the Gitea package registry:

http://chronicles-ab.waterschurch.org:3000/api/packages/christian/generic/bible-app/latest

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.

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:

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:

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:\ProgramData\Bible App\llama-cache\model.gguf; it is gitignored, so it never enters the repo), build the regular installer, then:

node tools/build-full-installer.cjs

Machines that already have the model keep using the regular installer.

6. Git

The tree lives on the church Gitea server:

http://chronicles-ab.waterschurch.org:3000/christian/bible-app

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).

Tag what you ship, so a rollback is a checkout rather than an archaeology exercise:

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

npm ci
npm start

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.