LibrePortal/scripts/release/make_release.sh
librelad 899e04bcd3 feat(regen): unified regeneration front door + self-heal poll
Add `lpRegen` (scripts/webui/webui_regen.sh) — one entry point that rebuilds the
file-derived artifacts whose sources changed, so callers don't have to know which
generator owns what. Self-heal is a cheap `find -newer` mtime compare (no watcher
/ daemon): a stage runs only when a source is newer than its artifact, or --force.

- `libreportal regen [all|webui|arrays] [--force]` CLI command (new category).
- Task processor idle tick runs a throttled `regen webui` poll, so an app dropped
  in out-of-band (drag-drop / marketplace) appears on its own — no manual command,
  no inotify (works on the relocatable/external-drive roots where inotify can't).
- make_release.sh guards against shipping stale source arrays (regenerate; abort
  if the committed tree was out of date), killing the "forgot generate_arrays" bug
  class at the build boundary.
- Document the front door in DEVELOPMENT.md.

webui scope rebuilds from containers/<app>/{*.config,tools/*.tools.json}; arrays
scope from scripts/** (a dev/build concern — a no-op on a normal install). Gate
logic verified in a sandbox (clean/config-newer/tools-newer/force/missing).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-25 23:20:02 +01:00

85 lines
3.5 KiB
Bash
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
# Build a versioned, checksum-verified LibrePortal release artifact.
#
# The stable install fetches a release tarball over plain HTTPS (no git, no auth),
# so it's reproducible and version-pinned. This builds that artifact from the
# COMMITTED tree via `git archive`, which honours the `export-ignore` rules in
# .gitattributes — so dev-only trees (scripts/unused, site, .claude, …) never ship.
#
# No infrastructure needed: output lands in dist/<channel>/ laid out exactly like
# the hosting will serve it, so you can point an install at it with:
# ( cd dist && python3 -m http.server 8000 )
# LP_RELEASE_BASE_URL=http://localhost:8000 ./install.sh ...
#
# Usage: scripts/release/make_release.sh [channel] [git-ref]
# channel stable (default) | edge
# git-ref HEAD (default) | a tag/commit to build from
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$REPO_ROOT"
CHANNEL="${1:-stable}"
REF="${2:-HEAD}"
VERSION="$(tr -d ' \t\n\r' < VERSION 2>/dev/null || true)"
[[ -n "$VERSION" ]] || { echo "make_release: VERSION file is empty or missing" >&2; exit 1; }
# Root-owned-footprint version (helpers/wrapper/unit/sudoers). Published in the
# manifest so the updater can detect when an update needs a root re-install.
FOOTPRINT_VERSION="$(grep -oE '^footprint_version=[0-9]+' init.sh | head -1 | cut -d= -f2)"
[[ -n "$FOOTPRINT_VERSION" ]] || FOOTPRINT_VERSION=0
# Guard: a release must never ship stale source arrays. Regenerate them; if that
# changes anything not committed, the tree was stale — abort and tell the dev to
# commit, so `git archive` (committed files only) can't bake in a mismatch. Only
# enforced when building HEAD (an explicit old tag/ref is taken as-is).
if [[ "$REF" == "HEAD" && -x scripts/source/files/generate_arrays.sh ]]; then
scripts/source/files/generate_arrays.sh run >/dev/null 2>&1 || true
if ! git diff --quiet -- scripts/source/files/arrays 2>/dev/null; then
echo "make_release: source arrays were stale — regenerated them now." >&2
echo " Commit the changes under scripts/source/files/arrays/ and re-run." >&2
exit 1
fi
fi
TARBALL="libreportal-${VERSION}.tar.gz"
PREFIX="libreportal-${VERSION}/" # top-level dir inside the tarball
OUT="$REPO_ROOT/dist/$CHANNEL"
mkdir -p "$OUT"
echo "Building $TARBALL (channel=$CHANNEL, ref=$REF) ..."
git archive --format=tar.gz --prefix="$PREFIX" -o "$OUT/$TARBALL" "$REF"
( cd "$OUT" && sha256sum "$TARBALL" > "$TARBALL.sha256" )
SHA="$(cut -d' ' -f1 < "$OUT/$TARBALL.sha256")"
cat > "$OUT/latest.json" <<EOF
{
"version": "$VERSION",
"channel": "$CHANNEL",
"url": "$TARBALL",
"sha256": "$SHA",
"footprint_version": $FOOTPRINT_VERSION,
"notes": ""
}
EOF
# Sign the tarball with minisign if a secret key is configured. Keep that key
# OFFLINE — set LP_MINISIGN_SECKEY to its path on the release machine only. The
# public half lives in libreportal.pub + install.sh; verification activates once
# you replace their REPLACE_ME placeholder. Produces <tarball>.minisig.
if [[ -n "${LP_MINISIGN_SECKEY:-}" ]]; then
command -v minisign >/dev/null 2>&1 || { echo "make_release: LP_MINISIGN_SECKEY set but 'minisign' isn't installed" >&2; exit 1; }
minisign -Sm "$OUT/$TARBALL" -s "$LP_MINISIGN_SECKEY" -t "libreportal $VERSION ($CHANNEL)" >/dev/null
SIGNED="$OUT/$TARBALL.minisig (signed)"
else
SIGNED=" unsigned (set LP_MINISIGN_SECKEY to sign)"
fi
echo "$OUT/$TARBALL"
echo "$OUT/$TARBALL.sha256 ($SHA)"
echo "$OUT/latest.json"
echo "$SIGNED"