#!/usr/bin/env sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P) PLUGIN_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd -P) DIST_DIR="$PLUGIN_DIR/dist" CONTRACT="$SCRIPT_DIR/production-contract.mjs" STAGING='' TARGET_PARENT='' cleanup() { status=$? trap - EXIT HUP INT TERM if [ -n "$STAGING" ] && [ -n "$TARGET_PARENT" ]; then case "$STAGING" in "$TARGET_PARENT"/.eln-template-filler.staging.*) if [ -d "$STAGING" ] && ! rm -rf "$STAGING"; then printf '%s\n' "Failed to clean release staging: $STAGING" >&2 [ "$status" -ne 0 ] || status=1 fi ;; *) printf '%s\n' 'Refusing to clean an unverified release staging path' >&2 [ "$status" -ne 0 ] || status=1 ;; esac fi exit "$status" } trap cleanup EXIT trap 'exit 129' HUP trap 'exit 130' INT trap 'exit 143' TERM fail() { printf '%s\n' "$1" >&2 exit "${2:-1}" } for command in diff mktemp node; do command -v "$command" >/dev/null 2>&1 || fail "$command is required to create a release" done [ -f "$CONTRACT" ] || fail "Missing production contract validator: $CONTRACT" [ -n "${ONLYOFFICE_RELEASE_ROOT:-}" ] || fail 'ONLYOFFICE_RELEASE_ROOT is required' RELEASE_ROOT=$(node -e ' const fs = require("node:fs"); const path = require("node:path"); let existing = path.resolve(process.argv[1]); const missing = []; while (!fs.existsSync(existing)) { missing.unshift(path.basename(existing)); const parent = path.dirname(existing); if (parent === existing) process.exit(2); existing = parent; } process.stdout.write(path.join(fs.realpathSync(existing), ...missing)); ' "$ONLYOFFICE_RELEASE_ROOT") [ "$RELEASE_ROOT" != '/' ] || fail 'ONLYOFFICE_RELEASE_ROOT must not be the filesystem root' [ "$RELEASE_ROOT" != "$PLUGIN_DIR" ] || fail 'ONLYOFFICE_RELEASE_ROOT must not be the plugin directory' case "$RELEASE_ROOT" in "$DIST_DIR" | "$DIST_DIR"/*) fail 'ONLYOFFICE_RELEASE_ROOT must not be dist or a directory inside dist' ;; esac [ -d "$DIST_DIR" ] || fail "Missing fresh production build directory: $DIST_DIR" node "$CONTRACT" validate-dist "$DIST_DIR" mkdir -p "$RELEASE_ROOT" TARGET=$(node "$CONTRACT" prepare-release-path "$RELEASE_ROOT") TARGET_PARENT=${TARGET%/*} STAGING=$(mktemp -d "$TARGET_PARENT/.eln-template-filler.staging.XXXXXX") node "$CONTRACT" copy-release "$DIST_DIR" "$STAGING" node "$CONTRACT" validate-release "$STAGING" if [ -e "$TARGET" ] || [ -L "$TARGET" ]; then [ ! -L "$TARGET" ] && [ -d "$TARGET" ] || fail "Immutable release target must be an ordinary directory: $TARGET" set +e diff -qr "$TARGET" "$STAGING" >/dev/null 2>&1 diff_status=$? set -e case "$diff_status" in 0) node "$CONTRACT" check-release "$TARGET" printf '%s\n' "$TARGET" exit 0 ;; 1) fail "Immutable release already exists with different content: $TARGET" ;; *) exit "$diff_status" ;; esac fi mv "$STAGING" "$TARGET" STAGING='' node "$CONTRACT" check-release "$TARGET" printf '%s\n' "$TARGET"