Compare commits

..
Author SHA1 Message Date
michael c11389473f Merge pull request 'Release builds: Intel disk images, a Windows bundle, and where to download them' (#24) from claude/release-builds into main 2026-09-30 09:58:11 -04:00
Waters ChurchandClaude Fable 5.1 c6a44e6ddc Windows build script: executable, like the Mac one
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 09:54:51 -04:00
Waters ChurchandClaude Fable 5.1 2f14b30d68 Windows bundle: no modules either, and the read-me says where they come from
The same change the Mac build got in 1.10.0: the bundle carries the shell
alone; the admin page's catalog installs modules into %APPDATA%\ProdDash.
README.txt gains the step.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-30 09:46:51 -04:00
Waters Church b5d39c60dc Merge remote-tracking branch 'origin/main' into claude/release-builds 2026-09-30 09:46:12 -04:00
michael 407eaecc23 Merge pull request 'Shell 1.10.0: a packaged ProdDash carries no modules' (#36) from claude/unbundled-shell into main 2026-09-30 09:42:23 -04:00
Waters ChurchandClaude Fable 5.1 b5c539ba05 Release builds: Intel disk images, a Windows bundle, and where to download them
launcher/macos/build.sh takes ARCH=x86_64 for Intel Macs — the Swift target
and the embedded Node follow (nodejs.org calls that one darwin-x64). The
default stays arm64.

launcher/windows/build.sh is new: the same payload plus Node for Windows,
checksum-verified against nodejs.org, and ProdDash.bat, which keeps the
server running and starts it again on exit code 75 — the admin page's update
restart — the way the macOS launcher does. No Windows launcher app yet.

The README's Run it section now points at the Releases page and the
ProdDash-releases repo that holds the files, one line each for Apple
silicon, Intel and Windows.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-24 17:53:19 -04:00
5 changed files with 160 additions and 5 deletions
+2
View File
@@ -14,6 +14,8 @@ modules/propresenter-timers/ltc-capture
# the launcher's build output, and its cache of the Node runtime it embeds # the launcher's build output, and its cache of the Node runtime it embeds
launcher/macos/build/ launcher/macos/build/
launcher/macos/.cache/ launcher/macos/.cache/
launcher/windows/build/
launcher/windows/.cache/
# Compiled per-machine, source sits next to it (see spl-capture.swift). # Compiled per-machine, source sits next to it (see spl-capture.swift).
modules/spl-meter/spl-capture modules/spl-meter/spl-capture
+26 -2
View File
@@ -30,9 +30,19 @@ and a clear degraded state, then recover on their own.
## Run it ## Run it
Ready-made builds are on the
[Releases page](http://chronicles-ab.waterschurch.org:3000/michael/ProdDash/releases);
the files themselves live in
[ProdDash-releases](http://chronicles-ab.waterschurch.org:3000/michael/ProdDash-releases).
There is a disk image for Apple silicon Macs, one for Intel Macs, and a
bundle for 64-bit Windows. Every build updates itself afterwards from the
admin page, so the download only has to be recent, not current.
### macOS — the app ### macOS — the app
Open the disk image and drag **ProdDash** to Applications. That's the whole Download the disk image for your Mac — `ProdDash-<version>-arm64.dmg` for
Apple silicon, `ProdDash-<version>-x86_64.dmg` for Intel — open it and drag
**ProdDash** to Applications. That's the whole
installation: the app carries the dashboard and its own Node runtime, so installation: the app carries the dashboard and its own Node runtime, so
nothing else has to be installed. It carries no modules — open **Admin → nothing else has to be installed. It carries no modules — open **Admin →
Available modules**, tick the ones this machine needs and press **Install Available modules**, tick the ones this machine needs and press **Install
@@ -45,12 +55,26 @@ a launchd job) simply doesn't have them, and an LTC input goes silently to
zeroes. zeroes.
Build the disk image from a checkout with Build the disk image from a checkout with
[launcher/macos](launcher/macos)/`build.sh`: [launcher/macos](launcher/macos)/`build.sh` (`ARCH=x86_64` in front of it
for Intel):
```bash ```bash
cd launcher/macos && ./build.sh --dmg cd launcher/macos && ./build.sh --dmg
``` ```
### Windows — the bundle
Download `ProdDash-<version>-win-x64.zip`, unzip it somewhere you can write
to — `C:\ProdDash`, say, not Program Files, because updates write into the
folder — and double-click **ProdDash.bat**. The window it opens is the
dashboard running: it stays open, and it starts the server again when the
admin page applies an update. Allow `node.exe` on private networks when the
firewall asks, so other screens can reach it. Settings and layouts live in
`%APPDATA%\ProdDash`, so a new bundle never loses them. To start with
Windows, put a shortcut to `ProdDash.bat` in `shell:startup`. There is no
menu-bar-style launcher for Windows yet; the bundle is built with
[launcher/windows](launcher/windows)/`build.sh`.
### Anywhere else, or from a checkout ### Anywhere else, or from a checkout
Requires [Node.js](https://nodejs.org) 18 or newer. Requires [Node.js](https://nodejs.org) 18 or newer.
+1
View File
@@ -51,6 +51,7 @@ the cycle rather than spinning forever.
```bash ```bash
./build.sh # build/ProdDash.app — the whole application ./build.sh # build/ProdDash.app — the whole application
./build.sh --dmg # …and build/ProdDash-<version>-arm64.dmg ./build.sh --dmg # …and build/ProdDash-<version>-arm64.dmg
ARCH=x86_64 ./build.sh --dmg # the same for Intel Macs (…-x86_64.dmg)
./build.sh --install # …and copy it to /Applications ./build.sh --install # …and copy it to /Applications
./build.sh --run # …and open it ./build.sh --run # …and open it
./build.sh --notarize # with --dmg: notarise and staple (Developer ID) ./build.sh --notarize # with --dmg: notarise and staple (Developer ID)
+10 -3
View File
@@ -13,6 +13,8 @@
# ./build.sh --dev launcher only — no Node, no server payload, so # ./build.sh --dev launcher only — no Node, no server payload, so
# it runs against the checkout. Seconds, not # it runs against the checkout. Seconds, not
# minutes, while working on the launcher itself. # minutes, while working on the launcher itself.
# ARCH=x86_64 ./build.sh the same for Intel Macs (default: arm64, Apple
# silicon); the Node it embeds follows.
# #
# Signing: a "Developer ID Application" certificate is used when one is # Signing: a "Developer ID Application" certificate is used when one is
# installed (override with CODESIGN_IDENTITY). Without one the app is signed # installed (override with CODESIGN_IDENTITY). Without one the app is signed
@@ -29,8 +31,13 @@ LAUNCHER_VERSION="1.0.0"
# The Node the app ships. Bump it here; the download is checksum-verified # The Node the app ships. Bump it here; the download is checksum-verified
# against nodejs.org's own SHASUMS256.txt and cached in .cache/. # against nodejs.org's own SHASUMS256.txt and cached in .cache/.
NODE_VERSION="v24.21.0" NODE_VERSION="v24.21.0"
ARCH="arm64" ARCH="${ARCH:-arm64}" # arm64 (Apple silicon) or x86_64 (Intel)
DEPLOYMENT_TARGET="13.0" DEPLOYMENT_TARGET="13.0"
case "$ARCH" in
arm64) NODE_ARCH="arm64" ;;
x86_64) NODE_ARCH="x64" ;; # nodejs.org's name for it
*) echo "build.sh: ARCH must be arm64 or x86_64, not $ARCH" >&2; exit 2 ;;
esac
REPO_ROOT="../.." REPO_ROOT="../.."
OUT_DIR="build" OUT_DIR="build"
@@ -108,7 +115,7 @@ fi
# ── the server, and the Node that runs it ──────────────────────────────── # ── the server, and the Node that runs it ────────────────────────────────
if [[ $DEV -eq 0 ]]; then if [[ $DEV -eq 0 ]]; then
TARBALL="node-$NODE_VERSION-darwin-$ARCH.tar.gz" TARBALL="node-$NODE_VERSION-darwin-$NODE_ARCH.tar.gz"
mkdir -p "$CACHE_DIR" mkdir -p "$CACHE_DIR"
if [[ ! -f "$CACHE_DIR/$TARBALL" ]]; then if [[ ! -f "$CACHE_DIR/$TARBALL" ]]; then
echo " fetching Node $NODE_VERSION (~50 MB, cached for next time)" echo " fetching Node $NODE_VERSION (~50 MB, cached for next time)"
@@ -127,7 +134,7 @@ if [[ $DEV -eq 0 ]]; then
echo " embedding Node $NODE_VERSION" echo " embedding Node $NODE_VERSION"
mkdir -p "$CONTENTS/Resources/node/bin" mkdir -p "$CONTENTS/Resources/node/bin"
tar -xzf "$CACHE_DIR/$TARBALL" -C "$CONTENTS/Resources/node/bin" --strip-components 2 \ tar -xzf "$CACHE_DIR/$TARBALL" -C "$CONTENTS/Resources/node/bin" --strip-components 2 \
"node-$NODE_VERSION-darwin-$ARCH/bin/node" "node-$NODE_VERSION-darwin-$NODE_ARCH/bin/node"
echo " embedding ProdDash $VERSION (no modules — the catalog installs them)" echo " embedding ProdDash $VERSION (no modules — the catalog installs them)"
mkdir -p "$PAYLOAD/config" mkdir -p "$PAYLOAD/config"
+121
View File
@@ -0,0 +1,121 @@
#!/bin/zsh
# Build the Windows bundle — ProdDash-<version>-win-x64.zip: the dashboard,
# its own Node runtime and a start script, so nothing has to be installed on
# the Windows machine. Unzip, double-click ProdDash.bat, done. It carries no
# modules: those come from the admin page's catalog into %APPDATA%\ProdDash.
#
# ./build.sh build/ProdDash-<version>-win-x64.zip
#
# Builds on macOS or Linux (zsh, curl, shasum, unzip, zip). Node for Windows
# comes from nodejs.org, checksum-verified against its SHASUMS256.txt and
# cached in .cache/. There is no Windows launcher app yet: ProdDash.bat keeps
# the server running and starts it again when the admin page applies an
# update (the server exits with code 75 to ask for that).
set -e -u
cd "$(dirname "$0")"
APP_NAME="ProdDash"
# The Node the bundle ships — keep in step with launcher/macos/build.sh.
NODE_VERSION="v24.21.0"
NODE_DIST="node-$NODE_VERSION-win-x64"
REPO_ROOT="../.."
OUT_DIR="build"
CACHE_DIR=".cache"
for tool in curl shasum unzip zip; do
command -v "$tool" >/dev/null || { echo "build.sh: $tool not found" >&2; exit 1; }
done
VERSION=$(sed -n 's/.*"version" *: *"\([^"]*\)".*/\1/p' "$REPO_ROOT/package.json" | head -1)
[[ -n "$VERSION" ]] || { echo "build.sh: can't read the version from package.json" >&2; exit 1; }
NAME="$APP_NAME-$VERSION-win-x64"
STAGE="$OUT_DIR/$NAME"
echo "ProdDash $VERSION — building the Windows bundle"
rm -rf "$OUT_DIR"
mkdir -p "$STAGE/node" "$STAGE/config" "$CACHE_DIR"
# ── Node for Windows ─────────────────────────────────────────────────────
ZIPFILE="$NODE_DIST.zip"
if [[ ! -f "$CACHE_DIR/$ZIPFILE" ]]; then
echo " fetching Node $NODE_VERSION for Windows (~30 MB, cached for next time)"
curl -fsSL --retry 3 -o "$CACHE_DIR/$ZIPFILE.part" "https://nodejs.org/dist/$NODE_VERSION/$ZIPFILE"
mv "$CACHE_DIR/$ZIPFILE.part" "$CACHE_DIR/$ZIPFILE"
fi
SUMS="$CACHE_DIR/SHASUMS256-$NODE_VERSION.txt"
[[ -f "$SUMS" ]] || curl -fsSL --retry 3 -o "$SUMS" "https://nodejs.org/dist/$NODE_VERSION/SHASUMS256.txt"
# This binary ships under ProdDash's name — check it every build.
WANT=$(awk -v f="$ZIPFILE" '$2 == f {print $1}' "$SUMS")
GOT=$(shasum -a 256 "$CACHE_DIR/$ZIPFILE" | awk '{print $1}')
if [[ -z "$WANT" || "$WANT" != "$GOT" ]]; then
echo "build.sh: $ZIPFILE does not match nodejs.org's checksum — refusing to ship it" >&2
exit 1
fi
echo " embedding Node $NODE_VERSION (node.exe and its licence)"
unzip -q -j "$CACHE_DIR/$ZIPFILE" "$NODE_DIST/node.exe" "$NODE_DIST/LICENSE" -d "$STAGE/node"
# ── ProdDash ─────────────────────────────────────────────────────────────
echo " embedding ProdDash $VERSION (no modules — the catalog installs them)"
cp "$REPO_ROOT/server.js" "$REPO_ROOT/package.json" "$STAGE/"
cp -R "$REPO_ROOT/public" "$STAGE/"
# Only the checked-in defaults: config/ also holds this machine's own
# modules.json and layouts when ProdDash has ever run from the checkout.
cp "$REPO_ROOT/config/proddash.json" "$STAGE/config/"
find "$STAGE" -name '.DS_Store' -delete
# ── the start script and the read-me, with Windows line endings ──────────
crlf() { awk '{ printf "%s\r\n", $0 }' > "$1"; }
crlf "$STAGE/ProdDash.bat" <<'BAT'
@echo off
rem ProdDash - double-click to start. Keep this window open: closing it stops the dashboard.
title ProdDash
cd /d "%~dp0"
rem The server exits with code 75 after applying an update from the admin page; start it again.
set PRODDASH_LAUNCHER=1
:run
"%~dp0node\node.exe" server.js
set CODE=%ERRORLEVEL%
if %CODE% EQU 75 goto run
echo.
echo ProdDash stopped (exit code %CODE%). Press any key to close this window.
pause >nul
BAT
crlf "$STAGE/README.txt" <<README
ProdDash $VERSION for Windows (64-bit)
=======================================
Nothing to install. This folder holds the dashboard and its own copy of Node.
1. Move this folder somewhere you can write to, for example C:\ProdDash
(not Program Files: updates write into this folder).
2. Double-click ProdDash.bat. A window opens and stays open while the
dashboard runs; closing it stops the dashboard.
- If Windows warns about the file, choose More info, then Run anyway.
- When Windows Defender Firewall asks about node.exe, allow it on
private networks so other screens can reach the dashboard.
3. Open http://localhost:24500 on this PC. Other devices on the network use
http://<this PC's IP address>:24500. Settings are on the admin page,
http://localhost:24500/admin.
4. The bundle ships without modules. On the admin page, tick the ones this
PC needs under Available modules and press Install selected; each one
updates on its own from then on.
Your settings and layouts live in %APPDATA%\ProdDash, not in this folder,
so unzipping a new version or updating never loses them.
Start with Windows: press Win+R, type shell:startup, press Enter, and put a
shortcut to ProdDash.bat in the folder that opens.
Updates: the admin page's Update now fetches the new version into this
folder and restarts the dashboard; the window stays open. A copy of the
version it replaced is kept for a short while in case the new one will not
start.
README
# ── zip ──────────────────────────────────────────────────────────────────
echo " zipping"
(cd "$OUT_DIR" && zip -q -r -X "$NAME.zip" "$NAME")
echo "built $OUT_DIR/$NAME.zip ($(du -sh "$OUT_DIR/$NAME.zip" | awk '{print $1}'))"