#!/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"
|