openvisengine/.zscripts/dev.sh
zai-bot 621bbc662c v7.15.3 — self-healing sandbox boot: tracked .env.ove + db seed + secrets/
Operator-authorized for the strictly private self-hosted Forgejo repo:
the env template (.env.ove), a baseline database snapshot
(db/custom.db.seed) and secrets/ now ride with the repo so sandbox
reprovisions can never wipe them. dev.sh self-heals at the very top
(before bun install): .env is restored from .env.ove whenever it lacks
OVE_DIRECTORY_API_KEY, and db/custom.db from the seed whenever it is
missing — verified end-to-end against a faithful reset simulation
(both [SELF-HEAL] restores fire, 106-preset library serves, directory
proxy authenticated, browser clean).

One evidence-driven deviation from the requested values: DATABASE_URL
is file:../db/custom.db, not file:./db/custom.db — Prisma resolves
relative SQLite paths against prisma/schema.prisma's directory, so the
./ form provably breaks both the CLI (would create a fresh empty db at
prisma/db/custom.db on every boot) and the runtime (cannot open); the
../ form is the portable equivalent and is documented in .env.ove's
header. secrets/ ships with a README documenting the house-cookie file
slots (the actual cookie exports are re-added by the operator).
2026-11-06 08:00:46 +00:00

186 lines
5.4 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
set -euo pipefail
# 获取脚本所在目录(.zscripts)
# 使用 $0 获取脚本路径(与 build.sh 保持一致)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
# ── Self-healing config restore (v7.15.3, worklog Task 47) ────────────────
# Sandbox reprovisions rewrite .env to a bare DATABASE_URL line and delete
# the untracked db/custom.db. The tracked .env.ove template and
# db/custom.db.seed baseline (authorized for this strictly private Forgejo
# repo) restore both automatically, before anything else runs, so the
# OVE-Directory proxy and the preset library survive every reset.
selfheal_restore_env() {
if [ ! -f "$PROJECT_DIR/.env" ] || ! grep -q '^OVE_DIRECTORY_API_KEY=' "$PROJECT_DIR/.env"; then
if [ -f "$PROJECT_DIR/.env.ove" ]; then
cp "$PROJECT_DIR/.env.ove" "$PROJECT_DIR/.env"
echo "[SELF-HEAL] .env restored from tracked .env.ove"
else
echo "[SELF-HEAL] WARNING: .env lacks OVE_DIRECTORY_API_KEY and no .env.ove template exists -- Directory tab will show NOT_CONFIGURED"
fi
fi
}
selfheal_restore_db() {
if [ ! -f "$PROJECT_DIR/db/custom.db" ]; then
if [ -f "$PROJECT_DIR/db/custom.db.seed" ]; then
mkdir -p "$PROJECT_DIR/db"
cp "$PROJECT_DIR/db/custom.db.seed" "$PROJECT_DIR/db/custom.db"
echo "[SELF-HEAL] db/custom.db restored from tracked db/custom.db.seed"
else
echo "[SELF-HEAL] WARNING: db/custom.db is missing and no db/custom.db.seed baseline exists -- db:push would seed an empty library"
fi
fi
}
selfheal_restore_env
selfheal_restore_db
log_step_start() {
local step_name="$1"
echo "=========================================="
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $step_name"
echo "=========================================="
export STEP_START_TIME
STEP_START_TIME=$(date +%s)
}
log_step_end() {
local step_name="${1:-Unknown step}"
local end_time
end_time=$(date +%s)
local duration=$((end_time - STEP_START_TIME))
echo "=========================================="
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Completed: $step_name"
echo "[LOG] Step: $step_name | Duration: ${duration}s"
echo "=========================================="
echo ""
}
start_mini_services() {
local mini_services_dir="$PROJECT_DIR/mini-services"
local started_count=0
log_step_start "Starting mini-services"
if [ ! -d "$mini_services_dir" ]; then
echo "Mini-services directory not found, skipping..."
log_step_end "Starting mini-services"
return 0
fi
echo "Found mini-services directory, scanning for sub-services..."
for service_dir in "$mini_services_dir"/*; do
if [ ! -d "$service_dir" ]; then
continue
fi
local service_name
service_name=$(basename "$service_dir")
echo "Checking service: $service_name"
if [ ! -f "$service_dir/package.json" ]; then
echo "[$service_name] No package.json found, skipping..."
continue
fi
if ! grep -q '"dev"' "$service_dir/package.json"; then
echo "[$service_name] No dev script found, skipping..."
continue
fi
echo "Starting $service_name in background..."
(
cd "$service_dir"
echo "[$service_name] Installing dependencies..."
bun install
echo "[$service_name] Running bun run dev..."
exec bun run dev
) >"$PROJECT_DIR/.zscripts/mini-service-${service_name}.log" 2>&1 &
local service_pid=$!
echo "[$service_name] Started in background (PID: $service_pid)"
echo "[$service_name] Log: $PROJECT_DIR/.zscripts/mini-service-${service_name}.log"
disown "$service_pid" 2>/dev/null || true
started_count=$((started_count + 1))
done
echo "Mini-services startup completed. Started $started_count service(s)."
log_step_end "Starting mini-services"
}
wait_for_service() {
local host="$1"
local port="$2"
local service_name="$3"
local max_attempts="${4:-60}"
local attempt=1
echo "Waiting for $service_name to be ready on $host:$port..."
while [ "$attempt" -le "$max_attempts" ]; do
if curl -s --connect-timeout 2 --max-time 5 "http://$host:$port" >/dev/null 2>&1; then
echo "$service_name is ready!"
return 0
fi
echo "Attempt $attempt/$max_attempts: $service_name not ready yet, waiting..."
sleep 1
attempt=$((attempt + 1))
done
echo "ERROR: $service_name failed to start within $max_attempts seconds"
return 1
}
cleanup() {
if [ -n "${DEV_PID:-}" ] && kill -0 "$DEV_PID" >/dev/null 2>&1; then
echo "Stopping Next.js dev server (PID: $DEV_PID)..."
kill "$DEV_PID" >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT INT TERM
cd "$PROJECT_DIR"
if ! command -v bun >/dev/null 2>&1; then
echo "ERROR: bun is not installed or not in PATH"
exit 1
fi
log_step_start "bun install"
echo "[BUN] Installing dependencies..."
bun install
log_step_end "bun install"
log_step_start "bun run db:push"
echo "[BUN] Setting up database..."
bun run db:push
log_step_end "bun run db:push"
log_step_start "Starting Next.js dev server"
echo "[BUN] Starting development server..."
bun run dev &
DEV_PID=$!
log_step_end "Starting Next.js dev server"
log_step_start "Waiting for Next.js dev server"
wait_for_service "localhost" "3000" "Next.js dev server"
log_step_end "Waiting for Next.js dev server"
log_step_start "Health check"
echo "[BUN] Performing health check..."
curl -fsS localhost:3000 >/dev/null
echo "[BUN] Health check passed"
log_step_end "Health check"
start_mini_services
echo "Next.js dev server is running in background (PID: $DEV_PID)."
echo "Use 'kill $DEV_PID' to stop it."
disown "$DEV_PID" 2>/dev/null || true
unset DEV_PID