Files
supervisor/scripts/release.sh
Timur Gordon 767c66fb6a initial commit
2025-08-26 14:49:21 +02:00

162 lines
5.0 KiB
Bash
Executable File

#!/bin/bash
# release.sh - Build optimized WASM and serve with Caddy + Brotli compression
set -e
###############################################################################
# Freezone Portal Release Script
# - Builds the WASM app with trunk in release mode
# - Optionally optimizes .wasm with wasm-opt (-Oz, strip)
# - Precompresses assets with gzip and brotli for efficient static serving
# - Generates a manifest (manifest.json) with sizes and SHA-256 checksums
#
# Usage:
# ./release.sh [--outdir dist] [--no-opt] [--compress] [--no-manifest]
# [--trunk-args "--public-url /portal/"]
#
# Notes:
# - Precompression is OFF by default; enable with --compress
# - Only modifies files within the output directory (default: dist)
# - Non-destructive to your source tree
###############################################################################
set -u
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PROJECT_DIR=$(cd "$SCRIPT_DIR/.." && pwd)
BUILD_SCRIPT="$SCRIPT_DIR/build.sh"
# Defaults
OUTDIR="dist"
DO_OPT=1
DO_COMPRESS=0
DO_MANIFEST=1
TRUNK_ARGS=""
usage() {
cat <<EOF
Usage: $(basename "$0") [options]
Options:
--outdir <dir> Output directory (default: dist)
--no-opt Skip wasm-opt optimization
--compress Enable gzip/brotli precompression
--no-manifest Skip manifest generation
--trunk-args "..." Extra arguments forwarded to trunk build
-h, --help Show this help
Examples:
$(basename "$0") --outdir dist --trunk-args "--public-url /"
$(basename "$0") --no-opt --no-compress
EOF
}
# Parse args
while [[ $# -gt 0 ]]; do
case "$1" in
--outdir)
OUTDIR="$2"; shift 2;;
--no-opt)
DO_OPT=0; shift;;
--compress)
DO_COMPRESS=1; shift;;
--no-manifest)
DO_MANIFEST=0; shift;;
--trunk-args)
TRUNK_ARGS="$2"; shift 2;;
-h|--help)
usage; exit 0;;
*)
echo "❌ Unknown option: $1"; echo; usage; exit 1;;
esac
done
# Tool checks
if [[ ! -x "$BUILD_SCRIPT" ]]; then
echo "❌ build.sh not found or not executable at: $BUILD_SCRIPT"
echo " Ensure portal/scripts/build.sh exists and is chmod +x."
exit 1
fi
if ! command -v trunk >/dev/null 2>&1; then
echo "❌ trunk not found. Install with: cargo install trunk"; exit 1;
fi
HAS_WASM_OPT=0
if command -v wasm-opt >/dev/null 2>&1; then HAS_WASM_OPT=1; fi
if [[ $DO_OPT -eq 1 && $HAS_WASM_OPT -eq 0 ]]; then
echo "⚠️ wasm-opt not found. Skipping WASM optimization."
DO_OPT=0
fi
if [[ $DO_COMPRESS -eq 1 ]]; then
if ! command -v gzip >/dev/null 2>&1; then
echo "⚠️ gzip not found. Skipping gzip compression."; GZIP_OK=0; else GZIP_OK=1; fi
if ! command -v brotli >/dev/null 2>&1; then
echo "⚠️ brotli not found. Skipping brotli compression."; BR_OK=0; else BR_OK=1; fi
else
GZIP_OK=0; BR_OK=0
fi
echo "🔧 Building optimized WASM bundle (via build.sh)..."
set -x
"$BUILD_SCRIPT" --release --outdir "$OUTDIR" ${TRUNK_ARGS:+--trunk-args "$TRUNK_ARGS"}
set +x
DIST_DIR="$PROJECT_DIR/$OUTDIR"
if [[ ! -d "$DIST_DIR" ]]; then
echo "❌ Build failed: output directory not found: $DIST_DIR"; exit 1;
fi
# Optimize .wasm files
if [[ $DO_OPT -eq 1 && $HAS_WASM_OPT -eq 1 ]]; then
echo "🛠️ Optimizing WASM with wasm-opt (-Oz, strip)..."
while IFS= read -r -d '' wasm; do
echo "$(basename "$wasm")"
tmp="$wasm.opt"
wasm-opt -Oz --strip-dwarf "$wasm" -o "$tmp"
mv "$tmp" "$wasm"
done < <(find "$DIST_DIR" -type f -name "*.wasm" -print0)
fi
# Precompress assets
if [[ $DO_COMPRESS -eq 1 ]]; then
echo "🗜️ Precompressing assets (gzip/brotli)..."
while IFS= read -r -d '' f; do
if [[ $GZIP_OK -eq 1 ]]; then
gzip -kf9 "$f"
fi
if [[ $BR_OK -eq 1 ]]; then
brotli -f -q 11 "$f"
fi
done < <(find "$DIST_DIR" -type f \( -name "*.wasm" -o -name "*.js" -o -name "*.css" \) -print0)
fi
# Manifest with sizes and SHA-256
if [[ $DO_MANIFEST -eq 1 ]]; then
echo "🧾 Generating manifest.json (sizes, sha256)..."
manifest="$DIST_DIR/manifest.json"
echo "{" > "$manifest"
first=1
while IFS= read -r -d '' f; do
rel="${f#"$DIST_DIR/"}"
size=$(stat -f%z "$f" 2>/dev/null || stat -c%s "$f")
if command -v shasum >/dev/null 2>&1; then
hash=$(shasum -a 256 "$f" | awk '{print $1}')
else
hash=$(openssl dgst -sha256 -r "$f" | awk '{print $1}')
fi
[[ $first -eq 1 ]] || echo "," >> "$manifest"
first=0
printf " \"%s\": { \"bytes\": %s, \"sha256\": \"%s\" }" "$rel" "$size" "$hash" >> "$manifest"
done < <(find "$DIST_DIR" -type f ! -name "manifest.json" -print0 | sort -z)
echo "\n}" >> "$manifest"
fi
echo "📦 Checking bundle sizes ($OUTDIR)..."
if [ -d "$OUTDIR" ]; then
echo "Bundle sizes:"
find "$OUTDIR" -name "*.wasm" -exec ls -lh {} \; | awk '{print " WASM: " $5 " - " $9}'
find "$OUTDIR" -name "*.js" -exec ls -lh {} \; | awk '{print " JS: " $5 " - " $9}'
find "$OUTDIR" -name "*.css" -exec ls -lh {} \; | awk '{print " CSS: " $5 " - " $9}'
echo ""
fi