88 lines
3.9 KiB
Bash
Executable File
88 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# wadamesh app+language store deploy: publish deploy/apps/ to the site VPS.
|
|
#
|
|
# The device reads BOTH catalogs from meshinfo.ru over plain HTTP:
|
|
# http://meshinfo.ru/firmware/apps/apps.json <- Store > Apps
|
|
# http://meshinfo.ru/firmware/apps/langs.json <- Store > Languages
|
|
# http://meshinfo.ru/firmware/apps/lang/<ver>/<code>.lang
|
|
# so this tree lives under /var/www/meshinfo/firmware/apps (nginx serves it both
|
|
# over HTTP, for the device, and HTTPS, for browsers).
|
|
#
|
|
# WHY THIS SCRIPT EXISTS: there wasn't one. release.sh rsyncs out/firmware/ (which
|
|
# does not contain apps/) and deploy-site.sh rsyncs deploy/site/ — so the store was
|
|
# only ever updated by someone remembering to rsync it by hand, and twice they did
|
|
# not. Translations sat at v8 on the server while the repo had v9/v10/v11, and a
|
|
# published app never appeared at all. Editing deploy/apps/ is not publishing it;
|
|
# running this is.
|
|
#
|
|
# Usage:
|
|
# WADAMESH_VPS=user@your-vps scripts/deploy-apps.sh # deploy
|
|
# WADAMESH_VPS=user@your-vps scripts/deploy-apps.sh --dry-run # preview only
|
|
#
|
|
# Optional:
|
|
# WADAMESH_FW_PATH=/var/www/meshinfo/firmware # override the web root
|
|
#
|
|
# The VPS target comes from the environment — never commit it.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SRC="$ROOT/deploy/apps/"
|
|
DEST="${WADAMESH_VPS:?set WADAMESH_VPS=user@host}"
|
|
DEST_PATH="${WADAMESH_FW_PATH:-/var/www/meshinfo/firmware}/apps"
|
|
|
|
DRY=""
|
|
[ "${1:-}" = "--dry-run" ] && DRY="--dry-run"
|
|
|
|
# Sanity-check the catalogs before shipping them: a device that gets malformed JSON
|
|
# shows an empty store with no clue why, and the versioned .lang dir each catalog
|
|
# entry points at has to actually exist or the download 404s on the device.
|
|
python3 - "$ROOT" <<'PY'
|
|
import json, os, sys
|
|
root = sys.argv[1]
|
|
apps_dir = os.path.join(root, "deploy", "apps")
|
|
langs = json.load(open(os.path.join(apps_dir, "langs.json")))["langs"]
|
|
missing = [f"{l['code']} v{l['ver']}" for l in langs
|
|
if not os.path.isfile(os.path.join(apps_dir, "lang", str(l["ver"]), l["code"] + ".lang"))]
|
|
if missing:
|
|
sys.exit("ABORT: langs.json points at files that do not exist: " + ", ".join(missing))
|
|
|
|
# The catalog version is what makes a device re-download a language. If it does
|
|
# not match the "# ver:" line inside the file, translators' work is published to
|
|
# a version nobody fetches and the change is invisible on device.
|
|
import re
|
|
drift = []
|
|
for l in langs:
|
|
f = os.path.join(apps_dir, "lang", str(l["ver"]), l["code"] + ".lang")
|
|
m = re.search(r"^# ver:\s*(\S+)", open(f, encoding="utf-8").read(), re.M)
|
|
if m and m.group(1) != str(l["ver"]):
|
|
drift.append(f"{l['code']}: catalog v{l['ver']} but file says v{m.group(1)}")
|
|
if drift:
|
|
sys.exit("ABORT: langs.json and the .lang headers disagree: " + "; ".join(drift))
|
|
|
|
# Same check for apps: an entry whose <id>/<ver>/<id>.lua is absent shows up in the
|
|
# Store and then fails to install, with nothing on screen to say why.
|
|
apps = json.load(open(os.path.join(apps_dir, "apps.json")))["apps"]
|
|
bad = []
|
|
for a in apps:
|
|
base = os.path.join(apps_dir, a["id"], a["ver"])
|
|
for f in (a["id"] + ".lua", a["id"] + ".json"):
|
|
if not os.path.isfile(os.path.join(base, f)):
|
|
bad.append(f'{a["id"]} v{a["ver"]}: {f}')
|
|
if bad:
|
|
sys.exit("ABORT: apps.json points at files that do not exist: " + ", ".join(bad))
|
|
print(f"catalogs ok: {len(langs)} languages and {len(apps)} apps, every referenced file present")
|
|
PY
|
|
|
|
# --delete mirrors the repo: the store is generated content, the repo is the source
|
|
# of truth, and stale versioned dirs left on the server are how a device ends up
|
|
# offered a language file nothing points at any more.
|
|
rsync -avz $DRY --delete "$SRC" "$DEST:$DEST_PATH/"
|
|
|
|
if [ -z "$DRY" ]; then
|
|
echo
|
|
echo "deployed deploy/apps/ -> $DEST:$DEST_PATH"
|
|
echo "verify:"
|
|
echo " curl -s http://meshinfo.ru/firmware/apps/langs.json"
|
|
echo " curl -s http://meshinfo.ru/firmware/apps/apps.json"
|
|
fi
|