98 lines
3.4 KiB
Bash
98 lines
3.4 KiB
Bash
#!/usr/bin/env sh
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname "$0")" && pwd)"
|
|
REPO_ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
RELEASE_VERSION="${RELEASE_VERSION:?RELEASE_VERSION is required}"
|
|
RELEASE_MANIFEST_SOURCE="${RELEASE_MANIFEST_SOURCE:?RELEASE_MANIFEST_SOURCE is required}"
|
|
RELEASE_ENV_SOURCE="${RELEASE_ENV_SOURCE:-$SCRIPT_DIR/managed-portal.env}"
|
|
OUTPUT_DIR="${OUTPUT_DIR:-$REPO_ROOT/dist/ota}"
|
|
STAGE_DIR="${OUTPUT_DIR}/managed-portal-${RELEASE_VERSION}"
|
|
BUNDLE_PATH="${OUTPUT_DIR}/managed-portal-${RELEASE_VERSION}.zip"
|
|
INSTALLER_PATH="${OUTPUT_DIR}/install-managed-portal-${RELEASE_VERSION}.sh"
|
|
INCLUDE_WEIGHTS="${INCLUDE_WEIGHTS:-0}"
|
|
PEOPLE_FLOW_WEIGHTS_SOURCE="${PEOPLE_FLOW_WEIGHTS_SOURCE:-$REPO_ROOT/managed/people_flow_project/weights}"
|
|
|
|
require_path() {
|
|
target="$1"
|
|
|
|
if [ ! -e "$target" ]; then
|
|
echo "missing required path: $target" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
dir_has_files() {
|
|
directory="$1"
|
|
[ -d "$directory" ] && [ -n "$(find "$directory" -mindepth 1 -print -quit 2>/dev/null)" ]
|
|
}
|
|
|
|
copy_dir() {
|
|
source_dir="$1"
|
|
target_dir="$2"
|
|
|
|
mkdir -p "$(dirname "$target_dir")"
|
|
cp -R "$source_dir" "$target_dir"
|
|
}
|
|
|
|
require_path "$RELEASE_MANIFEST_SOURCE"
|
|
require_path "$RELEASE_ENV_SOURCE"
|
|
require_path "$SCRIPT_DIR/docker-compose.ota-release.yml"
|
|
require_path "$SCRIPT_DIR/Dockerfile.runtime-overlay"
|
|
require_path "$SCRIPT_DIR/install-managed-portal-ota.sh"
|
|
require_path "$REPO_ROOT/managed/store_dwell_alert/config"
|
|
require_path "$REPO_ROOT/managed/people_flow_project/config"
|
|
|
|
rm -rf "$STAGE_DIR"
|
|
mkdir -p "$STAGE_DIR/deploy" "$OUTPUT_DIR"
|
|
|
|
cp "$SCRIPT_DIR/docker-compose.ota-release.yml" "$STAGE_DIR/deploy/docker-compose.ota-release.yml"
|
|
cp "$SCRIPT_DIR/Dockerfile.runtime-overlay" "$STAGE_DIR/deploy/Dockerfile.runtime-overlay"
|
|
cp "$RELEASE_ENV_SOURCE" "$STAGE_DIR/deploy/managed-portal.release.env"
|
|
cp "$RELEASE_MANIFEST_SOURCE" "$STAGE_DIR/release-manifest.env"
|
|
|
|
copy_dir "$REPO_ROOT/managed/store_dwell_alert/config" "$STAGE_DIR/managed/store_dwell_alert/config"
|
|
copy_dir "$REPO_ROOT/managed/people_flow_project/config" "$STAGE_DIR/managed/people_flow_project/config"
|
|
|
|
if [ "$INCLUDE_WEIGHTS" = "1" ]; then
|
|
if ! dir_has_files "$PEOPLE_FLOW_WEIGHTS_SOURCE"; then
|
|
echo "people-flow weights requested but missing under $PEOPLE_FLOW_WEIGHTS_SOURCE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
copy_dir "$PEOPLE_FLOW_WEIGHTS_SOURCE" "$STAGE_DIR/managed/people_flow_project/weights"
|
|
fi
|
|
|
|
python3 - "$OUTPUT_DIR" "$STAGE_DIR" "$BUNDLE_PATH" <<'PY'
|
|
from pathlib import Path
|
|
import sys
|
|
import zipfile
|
|
|
|
output_dir = Path(sys.argv[1])
|
|
stage_dir = Path(sys.argv[2])
|
|
bundle_path = Path(sys.argv[3])
|
|
|
|
if bundle_path.exists():
|
|
bundle_path.unlink()
|
|
|
|
with zipfile.ZipFile(bundle_path, "w", compression=zipfile.ZIP_DEFLATED) as archive:
|
|
for path in sorted(stage_dir.rglob("*")):
|
|
arcname = path.relative_to(output_dir)
|
|
if path.is_dir():
|
|
if not any(path.iterdir()):
|
|
archive.writestr(f"{arcname.as_posix().rstrip('/')}/", "")
|
|
continue
|
|
archive.write(path, arcname.as_posix())
|
|
PY
|
|
|
|
cp "$SCRIPT_DIR/install-managed-portal-ota.sh" "$INSTALLER_PATH"
|
|
chmod +x "$INSTALLER_PATH"
|
|
|
|
echo "OTA bundle created: $BUNDLE_PATH"
|
|
echo "Versioned installer created: $INSTALLER_PATH"
|
|
if [ "$INCLUDE_WEIGHTS" = "1" ]; then
|
|
echo "Bundle includes managed/people_flow_project/weights"
|
|
else
|
|
echo "Bundle excludes managed/people_flow_project/weights; the installer will reuse the shared host weights directory if available"
|
|
fi |