Files
Gmer4Lfe c377ddfcca Complete the header template across Partnership, Kernel, Deployment and Plugin
Finishes the pass: every script now documents its safeguards, and the deliberate absences
in the sourced libraries are recorded so they are not "corrected" later.
2026-08-01 22:44:23 -04:00

181 lines
8.9 KiB
Bash
Executable File

#!/bin/bash
# ==============================================================================================
# ============================= build.sh =======================================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Packages the plugin web files (Plugin/unraid/) into a Slackware .txz, the
# format unRAID re-installs from flash on every boot. This is the RELEASE path —
# for day-to-day development use plugin_setup.sh (symlink, instant edits).
#
# What it produces (in Plugin/dist/):
# varaverk-<version>-noarch-1.txz the package unRAID installs to
# /usr/local/emhttp/plugins/varaverk/
# varaverk-<version>-noarch-1.txz.sha256
#
# It also rewrites the <!ENTITY version> and <!ENTITY sha256> lines in
# Plugin/varaverk.plg so the .plg always points at the package just built.
#
# WHY a .txz (not the dev symlink):
# rc.local runs `plugin install` on every .plg at boot, BEFORE the array
# mounts. A symlink into /mnt/user/appdata can't be made that early (appdata
# isn't mounted) and the disks_mounted event hooks live behind that missing
# symlink — chicken-and-egg. A .txz lives on flash, so unRAID extracts it to
# RAM before the array starts; the event hooks are then present in time to
# rebuild cron when the array mounts. Scripts stay on appdata (git clone).
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
# 1. Resolve version — first argument, else today's date as YYYY.MM.DD
# 2. Verify makepkg exists (Slackware tooling — this only runs on unRAID)
# 3. Stage Plugin/unraid/ into the install layout the package expects
# 4. makepkg the stage into Plugin/dist/<name>-<version>-noarch-1.txz
# 5. sha256sum the result and write the .sha256 alongside it
# 6. Rewrite <!ENTITY version> and <!ENTITY sha256> in varaverk.plg so the .plg
# always points at the package just built
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Release Path, Not the Dev Path
# Day-to-day work uses plugin_setup.sh, which symlinks the source directory so edits are
# live immediately. This produces the artifact unRAID reinstalls from flash on every boot.
# Keeping the two separate is what allows fast iteration without shipping half-finished
# files into a package.
#
# The .plg Always Matches the Package
# Version and checksum are written into varaverk.plg in the same run that produces the
# .txz. A .plg pointing at a checksum it was not built against fails to install with a
# mismatch error, so the two are never updated independently.
#
# Date Version by Default
# An omitted version becomes today's date. Builds are therefore always ordered and always
# unique without anyone maintaining a counter.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
# No Root — Deliberate
# Writes only into Plugin/dist/ and rewrites varaverk.plg inside the repo. It installs
# nothing and touches nothing under /usr or /boot, so it needs no privilege. Requiring
# root would mean building release artifacts as root for no reason.
#
# makepkg Presence Check
# Aborts immediately if makepkg is missing, with a note that this runs on unRAID. The
# Slackware toolchain is not present on a normal dev machine and a partial build would be
# worse than a clear refusal.
#
# Checksum Written From the Real Artifact
# The sha256 is computed from the .txz that was just produced, never assumed or carried
# forward, so the .plg cannot advertise a checksum for a different build.
#
# Staged Build
# The package is assembled from a staging directory rather than from the live source
# tree, so an in-progress edit cannot end up inside a release artifact.
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# None — this is a build tool, not a runtime script. It reads no conf and calls no
# load_config.sh.
#
# Inputs are positional and derived:
# $1 version string (default: today, YYYY.MM.DD)
# Plugin/unraid/ source tree that gets packaged
# Plugin/varaverk.plg rewritten in place with the new version and checksum
#
# Output: Plugin/dist/<name>-<version>-noarch-1.txz and its .sha256
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# ./build.sh
# Build with today's date as version (YYYY.MM.DD).
#
# ./build.sh 2026.09.01
# Build with an explicit version string.
#
# After building: commit Plugin/dist/<txz> + the updated .plg, then attach the
# .txz to a GitHub release tagged <version> so the .plg URL resolves for
# downloaders. (The .plg also works offline if the .txz is already cached on
# flash with a matching SHA256.)
#
# ==============================================================================================
set -euo pipefail
PLUGIN_NAME="varaverk"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SRC="$SCRIPT_DIR/unraid"
DIST="$SCRIPT_DIR/dist"
PLG="$SCRIPT_DIR/varaverk.plg"
VERSION="${1:-$(date +%Y.%m.%d)}"
PKG_BASENAME="${PLUGIN_NAME}-${VERSION}-noarch-1"
OUTFILE="$DIST/${PKG_BASENAME}.txz"
# ── Guards ──────────────────────────────────────────────────────────────────
[[ -d "$SRC" ]] || { echo "ERROR: source not found: $SRC"; exit 1; }
command -v makepkg >/dev/null || { echo "ERROR: makepkg not found (run on unRAID)"; exit 1; }
mkdir -p "$DIST"
# ── Stage files under the real install path ─────────────────────────────────
# installpkg extracts relative to / so the package must contain the full path.
STAGE="$(mktemp -d)"
trap 'rm -rf "$STAGE"' EXIT
INSTALL_ROOT="$STAGE/usr/local/emhttp/plugins/$PLUGIN_NAME"
mkdir -p "$INSTALL_ROOT"
# Copy web files; drop VCS/editor cruft and any dev-only leftovers.
cp -a "$SRC/." "$INSTALL_ROOT/"
find "$INSTALL_ROOT" -name '.git*' -prune -exec rm -rf {} + 2>/dev/null || true
find "$INSTALL_ROOT" -name '*.swp' -delete 2>/dev/null || true
# Normalise ownership/permissions inside the package.
chown -R root:root "$STAGE" 2>/dev/null || true
find "$INSTALL_ROOT" -type d -exec chmod 0755 {} +
find "$INSTALL_ROOT" -type f -exec chmod 0644 {} +
# Keep shell/event scripts executable.
find "$INSTALL_ROOT" \( -name '*.sh' -o -path '*/event/*' \) -type f -exec chmod 0755 {} +
# ── Build the package ───────────────────────────────────────────────────────
# makepkg doesn't quote its output arg internally, so build to a space-free temp
# path (the repo lives under a dir with spaces) then move into dist/.
TMP_OUT="$STAGE.txz"
( cd "$STAGE" && makepkg -l y -c y "$TMP_OUT" >/dev/null )
mv "$TMP_OUT" "$OUTFILE"
# ── Hash + record ───────────────────────────────────────────────────────────
SHA256="$(sha256sum "$OUTFILE" | awk '{print $1}')"
echo "$SHA256 ${PKG_BASENAME}.txz" > "$OUTFILE.sha256"
# ── Point the .plg at this build ────────────────────────────────────────────
if [[ -f "$PLG" ]]; then
sed -i -E "s|(<!ENTITY[[:space:]]+version[[:space:]]+\")[^\"]*(\">)|\1${VERSION}\2|" "$PLG"
sed -i -E "s|(<!ENTITY[[:space:]]+sha256[[:space:]]+\")[^\"]*(\">)|\1${SHA256}\2|" "$PLG"
fi
SIZE="$(numfmt --to=iec "$(stat -c %s "$OUTFILE")")"
cat <<EOF
Built: $OUTFILE ($SIZE)
Version: $VERSION
SHA256: $SHA256
.plg updated (version + sha256).
Next:
1) git add Plugin/dist/${PKG_BASENAME}.txz* Plugin/varaverk.plg && commit
2) Create GitHub release tagged "$VERSION", attach ${PKG_BASENAME}.txz
(skip for a local/offline install — copy the .txz to
/boot/config/plugins/$PLUGIN_NAME/ and the .plg uses the cached copy)
EOF