#!/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--noarch-1.txz the package unRAID installs to # /usr/local/emhttp/plugins/varaverk/ # varaverk--noarch-1.txz.sha256 # # It also rewrites the and 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/--noarch-1.txz # 5. sha256sum the result and write the .sha256 alongside it # 6. Rewrite and 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/--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/ + the updated .plg, then attach the # .txz to a GitHub release tagged 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|()|\1${VERSION}\2|" "$PLG" sed -i -E "s|()|\1${SHA256}\2|" "$PLG" fi SIZE="$(numfmt --to=iec "$(stat -c %s "$OUTFILE")")" cat <