Files
eggent/scripts/install-local.sh
2026-02-25 16:14:15 +03:00

196 lines
4.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENV_FILE="$ROOT_DIR/.env"
ENV_EXAMPLE_FILE="$ROOT_DIR/.env.example"
require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing dependency: $1" >&2
exit 1
fi
}
warn_if_missing_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "WARNING: Recommended utility is missing: $1" >&2
fi
}
check_node_version() {
local version major
version="$(node -p "process.versions.node")"
major="${version%%.*}"
if [[ "$major" -lt 20 ]]; then
echo "Node.js 20+ is required (found $version)." >&2
exit 1
fi
}
upsert_env() {
local file="$1"
local key="$2"
local value="$3"
local tmp found line
tmp="$(mktemp)"
found=0
if [[ -f "$file" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
if [[ "$line" == "$key="* ]]; then
printf '%s=%s\n' "$key" "$value" >>"$tmp"
found=1
else
printf '%s\n' "$line" >>"$tmp"
fi
done <"$file"
fi
if [[ "$found" -eq 0 ]]; then
printf '%s=%s\n' "$key" "$value" >>"$tmp"
fi
mv "$tmp" "$file"
}
get_env_value() {
local file="$1"
local key="$2"
if [[ ! -f "$file" ]]; then
return 0
fi
grep -E "^${key}=" "$file" | tail -n 1 | cut -d= -f2- || true
}
looks_placeholder() {
local value="$1"
if [[ -z "$value" ]]; then
return 0
fi
case "$value" in
replace-with-* | *replace-with* | changeme | example | ... )
return 0
;;
*)
return 1
;;
esac
}
random_hex() {
local bytes="${1:-32}"
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex "$bytes"
return 0
fi
node -e "process.stdout.write(require('node:crypto').randomBytes(${bytes}).toString('hex'))"
}
wait_for_health() {
local url="$1"
local retries="$2"
local delay="$3"
local i
for i in $(seq 1 "$retries"); do
if command -v curl >/dev/null 2>&1; then
if curl --silent --show-error --fail "$url" >/dev/null 2>&1; then
return 0
fi
else
if node -e "fetch(process.argv[1]).then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" "$url"; then
return 0
fi
fi
sleep "$delay"
done
return 1
}
echo "==> Local production setup (npm)"
require_cmd node
require_cmd npm
require_cmd python3
require_cmd curl
check_node_version
warn_if_missing_cmd git
warn_if_missing_cmd jq
warn_if_missing_cmd pip3
warn_if_missing_cmd rg
cd "$ROOT_DIR"
if [[ ! -f "$ENV_FILE" ]]; then
if [[ ! -f "$ENV_EXAMPLE_FILE" ]]; then
echo "Missing template file: $ENV_EXAMPLE_FILE" >&2
exit 1
fi
cp "$ENV_EXAMPLE_FILE" "$ENV_FILE"
echo "Created .env from .env.example"
fi
EXTERNAL_API_TOKEN_VALUE="$(get_env_value "$ENV_FILE" "EXTERNAL_API_TOKEN")"
if looks_placeholder "$EXTERNAL_API_TOKEN_VALUE"; then
upsert_env "$ENV_FILE" "EXTERNAL_API_TOKEN" "$(random_hex 32)"
echo "Generated EXTERNAL_API_TOKEN in .env"
fi
TELEGRAM_WEBHOOK_SECRET_VALUE="$(get_env_value "$ENV_FILE" "TELEGRAM_WEBHOOK_SECRET")"
if looks_placeholder "$TELEGRAM_WEBHOOK_SECRET_VALUE"; then
upsert_env "$ENV_FILE" "TELEGRAM_WEBHOOK_SECRET" "$(random_hex 24)"
echo "Generated TELEGRAM_WEBHOOK_SECRET in .env"
fi
EGGENT_AUTH_SECRET_VALUE="$(get_env_value "$ENV_FILE" "EGGENT_AUTH_SECRET")"
if looks_placeholder "$EGGENT_AUTH_SECRET_VALUE"; then
upsert_env "$ENV_FILE" "EGGENT_AUTH_SECRET" "$(random_hex 32)"
echo "Generated EGGENT_AUTH_SECRET in .env"
fi
chmod 600 "$ENV_FILE" 2>/dev/null || true
mkdir -p "$ROOT_DIR/data"
echo "==> Installing dependencies"
npm install --no-package-lock
echo "==> Building production bundle"
npm run build
HEALTH_PORT="${HEALTH_PORT:-3077}"
HEALTH_URL="http://127.0.0.1:${HEALTH_PORT}/api/health"
START_LOG="$ROOT_DIR/.install-local-start.log"
echo "==> Running smoke check: $HEALTH_URL"
PORT="$HEALTH_PORT" HOSTNAME="127.0.0.1" npm run start >"$START_LOG" 2>&1 &
START_PID=$!
cleanup() {
if kill -0 "$START_PID" >/dev/null 2>&1; then
kill "$START_PID" >/dev/null 2>&1 || true
wait "$START_PID" >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT
if ! wait_for_health "$HEALTH_URL" 45 1; then
echo "Smoke check failed. Server log tail:" >&2
tail -n 120 "$START_LOG" >&2 || true
exit 1
fi
rm -f "$START_LOG"
cleanup
trap - EXIT
echo ""
echo "Setup complete."
echo "Run in production mode:"
echo " npm run start"
echo ""
echo "App URL:"
echo " http://127.0.0.1:3000"