feat: sync portal runtime fixes for release
This commit is contained in:
@@ -3,12 +3,24 @@ set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
NODE_BIN="${NODE_BIN:-/opt/homebrew/opt/node@24/bin/node}"
|
||||
DEFAULT_MONITOR_SCRIPT="$ROOT/scripts/monitor-goosed-fds.mjs"
|
||||
if [[ -x "/Users/john/Project/tkmind_go/scripts/monitor-goosed-fds.mjs" ]]; then
|
||||
DEFAULT_MONITOR_SCRIPT="/Users/john/Project/tkmind_go/scripts/monitor-goosed-fds.mjs"
|
||||
fi
|
||||
MONITOR_SCRIPT="${GOOSED_MONITOR_SCRIPT:-$DEFAULT_MONITOR_SCRIPT}"
|
||||
MONITOR_ROOT="$(cd "$(dirname "$MONITOR_SCRIPT")/.." && pwd)"
|
||||
PLIST="$HOME/Library/LaunchAgents/cn.tkmind.goosed-monitor.plist"
|
||||
LOG="$HOME/Library/Logs/goosed-monitor.log"
|
||||
GUI="gui/$(id -u)"
|
||||
|
||||
mkdir -p "$HOME/Library/LaunchAgents" "$HOME/Library/Logs"
|
||||
|
||||
if [[ ! -x "$MONITOR_SCRIPT" ]]; then
|
||||
echo "monitor script not found or not executable: $MONITOR_SCRIPT" >&2
|
||||
echo "Set GOOSED_MONITOR_SCRIPT to a stable goosed ops script path." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > "$PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
@@ -19,10 +31,10 @@ cat > "$PLIST" <<EOF
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>$NODE_BIN</string>
|
||||
<string>$ROOT/scripts/monitor-goosed-fds.mjs</string>
|
||||
<string>$MONITOR_SCRIPT</string>
|
||||
</array>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>$ROOT</string>
|
||||
<string>$MONITOR_ROOT</string>
|
||||
<key>StartInterval</key>
|
||||
<integer>60</integer>
|
||||
<key>RunAtLoad</key>
|
||||
@@ -55,4 +67,5 @@ launchctl enable "$GUI/cn.tkmind.goosed-monitor"
|
||||
launchctl kickstart -k "$GUI/cn.tkmind.goosed-monitor"
|
||||
|
||||
echo "installed $PLIST"
|
||||
echo "script: $MONITOR_SCRIPT"
|
||||
echo "log: $LOG"
|
||||
|
||||
@@ -80,7 +80,39 @@ need_cmd scp
|
||||
need_cmd tar
|
||||
need_cmd shasum
|
||||
|
||||
check_release_scope() {
|
||||
local bypass="${ALLOW_PORTAL_RELEASE_SCOPE_BYPASS:-0}"
|
||||
if [[ "${bypass}" == "1" ]]; then
|
||||
say "跳过发版范围检查(ALLOW_PORTAL_RELEASE_SCOPE_BYPASS=1)"
|
||||
return 0
|
||||
fi
|
||||
git -C "${ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
|
||||
|
||||
local path
|
||||
local blocked=()
|
||||
while IFS= read -r path; do
|
||||
[[ -n "${path}" ]] || continue
|
||||
case "${path}" in
|
||||
docker/*|scripts/start-goosed-local.sh|scripts/verify-goosed-docker.sh|docs/goosed-*.md|server.mjs.bak*|*.bak)
|
||||
blocked+=("${path}")
|
||||
;;
|
||||
docs/local-dev.md|README.md)
|
||||
blocked+=("${path}")
|
||||
;;
|
||||
esac
|
||||
done < <(git -C "${ROOT}" status --short --untracked-files=all | sed -E 's/^.. //')
|
||||
|
||||
if [[ "${#blocked[@]}" -gt 0 ]]; then
|
||||
echo "检测到默认不应并入 103 Portal 发版的本地改动:" >&2
|
||||
printf ' - %s\n' "${blocked[@]}" >&2
|
||||
echo "请先清理这些改动,或确认本次需求明确包含这些模块后再重试。" >&2
|
||||
echo "如确需绕过,可临时设置 ALLOW_PORTAL_RELEASE_SCOPE_BYPASS=1。" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
say "本地预检查"
|
||||
check_release_scope
|
||||
ssh -o BatchMode=yes -o ConnectTimeout=15 "${HOST}" "echo portal-runtime-ssh-ok" >/dev/null
|
||||
ssh -o BatchMode=yes "${HOST}" "test -d '${APP_DIR}' && test -f '${APP_DIR}/.env'" >/dev/null
|
||||
|
||||
@@ -121,6 +153,87 @@ verify_runtime_artifact() {
|
||||
|
||||
verify_runtime_artifact
|
||||
|
||||
verify_remote_goosed_dependency() {
|
||||
say "检查 103 goosed 依赖"
|
||||
ssh -o BatchMode=yes "${HOST}" 'bash -s' <<'REMOTE'
|
||||
set -euo pipefail
|
||||
|
||||
missing=0
|
||||
|
||||
docker_bin="/opt/homebrew/bin/docker"
|
||||
if [[ -x "${docker_bin}" ]] && "${docker_bin}" ps --format '{{.Names}}' 2>/dev/null | grep -q '^goosed-prod-1$'; then
|
||||
for index in 1 2 3 4; do
|
||||
container="goosed-prod-${index}"
|
||||
host_port=$((18005 + index))
|
||||
if ! "${docker_bin}" ps --format '{{.Names}} {{.Ports}} {{.Status}}' | grep -q "^${container} .*0.0.0.0:${host_port}->18006/tcp.*healthy"; then
|
||||
echo "goosed dependency check failed: ${container} is not healthy on host port ${host_port}" >&2
|
||||
missing=1
|
||||
fi
|
||||
if ! "${docker_bin}" exec "${container}" sh -lc 'test -x /usr/local/bin/node && test -f /opt/portal/mindspace-sandbox-mcp.mjs' >/dev/null 2>&1; then
|
||||
echo "goosed dependency check failed: ${container} missing /usr/local/bin/node or /opt/portal/mindspace-sandbox-mcp.mjs" >&2
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
if [[ -f /Users/john/Project/Memind/.env ]]; then
|
||||
portal_mcp_node="$(grep -E '^GOOSED_MCP_NODE_PATH=' /Users/john/Project/Memind/.env | tail -1 | cut -d= -f2- || true)"
|
||||
portal_mcp_server="$(grep -E '^GOOSED_MCP_SERVER_PATH=' /Users/john/Project/Memind/.env | tail -1 | cut -d= -f2- || true)"
|
||||
if [[ -z "${portal_mcp_node}" || -z "${portal_mcp_server}" ]]; then
|
||||
echo "goosed dependency check failed: Portal .env must set GOOSED_MCP_NODE_PATH and GOOSED_MCP_SERVER_PATH for Docker goosed" >&2
|
||||
missing=1
|
||||
else
|
||||
for index in 1 2 3 4; do
|
||||
container="goosed-prod-${index}"
|
||||
if ! "${docker_bin}" exec "${container}" sh -lc "test -x '${portal_mcp_node}' && test -f '${portal_mcp_server}'" >/dev/null 2>&1; then
|
||||
echo "goosed dependency check failed: ${container} cannot resolve Portal .env MCP paths '${portal_mcp_node}' and '${portal_mcp_server}'" >&2
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
else
|
||||
for port in 18006 18007; do
|
||||
line="$(lsof -nP -iTCP:${port} -sTCP:LISTEN 2>/dev/null | awk 'NR==2 {print $1, $2, $9}')"
|
||||
if [[ -z "${line}" ]]; then
|
||||
echo "goosed dependency check failed: port ${port} has no listener" >&2
|
||||
missing=1
|
||||
continue
|
||||
fi
|
||||
command_name="${line%% *}"
|
||||
case "${command_name}" in
|
||||
goosed) ;;
|
||||
*)
|
||||
echo "goosed dependency check failed: port ${port} is listened by ${line}, not goosed" >&2
|
||||
missing=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if ! launchctl list 2>/dev/null | grep -q 'cn.tkmind.goosed-18006'; then
|
||||
echo "goosed dependency check failed: launchd service cn.tkmind.goosed-18006 is not loaded" >&2
|
||||
missing=1
|
||||
fi
|
||||
if ! launchctl list 2>/dev/null | grep -q 'cn.tkmind.goosed-18007'; then
|
||||
echo "goosed dependency check failed: launchd service cn.tkmind.goosed-18007 is not loaded" >&2
|
||||
missing=1
|
||||
fi
|
||||
if [[ ! -x /Users/john/Project/tkmind_go/scripts/run-goosed-local.sh ]]; then
|
||||
echo "goosed dependency check failed: missing /Users/john/Project/tkmind_go/scripts/run-goosed-local.sh" >&2
|
||||
missing=1
|
||||
fi
|
||||
if [[ ! -x /Users/john/Project/tkmind_go/target/release/goosed && ! -x /Users/john/Project/tkmind_go/target/debug/goosed ]]; then
|
||||
echo "goosed dependency check failed: missing goosed binary under /Users/john/Project/tkmind_go/target" >&2
|
||||
missing=1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit "${missing}"
|
||||
REMOTE
|
||||
}
|
||||
|
||||
if [[ "${DRY_RUN}" -ne 1 ]]; then
|
||||
verify_remote_goosed_dependency
|
||||
fi
|
||||
|
||||
if [[ "${AUTO_YES}" -ne 1 && "${DRY_RUN}" -ne 1 ]]; then
|
||||
say "发布确认"
|
||||
echo "目标主机: ${HOST}"
|
||||
|
||||
@@ -15,6 +15,7 @@ fi
|
||||
export NODE_ENV=production
|
||||
export H5_PORT="${H5_PORT:-8081}"
|
||||
export H5_PUBLIC_BASE_URL="https://m.tkmind.cn"
|
||||
export TKMIND_API_TARGETS="${TKMIND_API_TARGETS_OVERRIDE:-${TKMIND_API_TARGETS:-https://127.0.0.1:18006,https://127.0.0.1:18007,https://127.0.0.1:18008,https://127.0.0.1:18009}}"
|
||||
export TKMIND_API_TARGET="${TKMIND_API_TARGET_OVERRIDE:-https://127.0.0.1:18006}"
|
||||
export TKMIND_API_TARGET_1="${TKMIND_API_TARGET_1_OVERRIDE:-https://127.0.0.1:18007}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user