From 25c7bd75aab4832a21354ea33f1aedc66e4f923a Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Thu, 18 Jun 2026 21:09:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(client+scripts):=20release=20=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E7=9C=9F=E6=B5=8B=20=E2=80=94=20local=5Ftest.sh=20+?= =?UTF-8?q?=20=E5=86=85=E6=A0=B8=E6=9F=A5=E6=89=BE=E5=8A=A0=20/opt/homebre?= =?UTF-8?q?w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scripts/local_test.sh:一键构建 release macOS 包 + 配 sing-box 免密 sudoers (TUN 需 root)+ 前台运行真身(日志直出),让本地测试 = release 线上行为 - kernel_process 二进制查找兜底加 /opt/homebrew/bin/sing-box(Apple Silicon brew),release 包从 Finder/直接启动也能找到内核,免设 PANGOLIN_SINGBOX_BIN Co-Authored-By: Claude Opus 4.8 --- client/lib/bridge/kernel_process.dart | 13 +++++-- scripts/local_test.sh | 55 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) create mode 100755 scripts/local_test.sh diff --git a/client/lib/bridge/kernel_process.dart b/client/lib/bridge/kernel_process.dart index 127634a..5fe8c4c 100644 --- a/client/lib/bridge/kernel_process.dart +++ b/client/lib/bridge/kernel_process.dart @@ -11,7 +11,8 @@ // 2. /sing-box (或 .exe) // 3. /../../Resources/sing-box (macOS .app bundle) // 4. /app/kernel/dist/desktop/-/sing-box (开发目录) -// 5. /usr/local/bin/sing-box +// 5. /opt/homebrew/bin/sing-box (Apple Silicon brew) +// 6. /usr/local/bin/sing-box (Intel brew / Linux) // · 配置 Clash API 端口: 由 spawn 调用方(DesktopVpnBridge)写入配置, // 或从配置文件读 experimental.clash_api.external_controller // @@ -601,9 +602,13 @@ class DesktopKernelProcess implements KernelProcess { } } - // 系统 PATH 兜底 - const fallback = '/usr/local/bin/sing-box'; - if (await File(fallback).exists()) return fallback; + // 系统常见安装路径兜底(Apple Silicon brew / Intel·Linux brew) + for (final fallback in const [ + '/opt/homebrew/bin/sing-box', + '/usr/local/bin/sing-box', + ]) { + if (await File(fallback).exists()) return fallback; + } throw FileSystemException( 'sing-box binary not found. ' diff --git a/scripts/local_test.sh b/scripts/local_test.sh new file mode 100755 index 0000000..f365d77 --- /dev/null +++ b/scripts/local_test.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# local_test.sh —— 一键构建并运行【release】版 macOS 客户端,连真实节点做端到端验证。 +# +# 用真正的 release 包(不是 dev 模拟),前台运行以便直接看内核(sing-box)日志。 +# 改完代码直接跑此脚本即可。 +# +# bash scripts/local_test.sh +# +# 可选环境变量: +# PANGOLIN_API_URL 控制面地址(默认连 racknerd 节点) +# SINGBOX_BIN sing-box 路径(默认 brew 的 /opt/homebrew/bin/sing-box) +# +# 前置:flutter、sing-box(brew install sing-box)、已在 Xcode 配好签名团队。 +# TUN 需 root → 脚本会装一条 NOPASSWD sudoers(一次性,可能让你输一次电脑密码)。 +# 正式版会用 SMJobBless 特权 Helper 取代 sudo(BACKLOG-11D-HELPER)。 +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +CLIENT="$REPO_ROOT/client" +API_URL="${PANGOLIN_API_URL:-http://107.172.55.251:8080}" +SINGBOX="${SINGBOX_BIN:-/opt/homebrew/bin/sing-box}" + +command -v flutter >/dev/null 2>&1 || { echo "✗ 需要 flutter"; exit 1; } +[ -x "$SINGBOX" ] || { echo "✗ 找不到 sing-box: $SINGBOX(brew install sing-box,或设 SINGBOX_BIN)"; exit 1; } + +# ── 1. TUN 免密 sudoers(幂等;命令路径须与客户端解析到的一致)────────────────── +echo "==> [1/3] 配置 sing-box 免密 sudo(TUN 需 root)" +SUDO_FILE=/etc/sudoers.d/pangolin-singbox +WANT="$(whoami) ALL=(root) NOPASSWD: $SINGBOX" +TMP="$(mktemp)" +printf '%s\n' "$WANT" > "$TMP" +# 校验语法后安装(避免写坏 sudoers) +if sudo visudo -cf "$TMP" >/dev/null 2>&1; then + sudo install -m 440 -o root -g wheel "$TMP" "$SUDO_FILE" + echo " 已写入 $SUDO_FILE: $WANT" +else + echo "✗ sudoers 语法校验失败"; rm -f "$TMP"; exit 1 +fi +rm -f "$TMP" + +# ── 2. 构建 release ─────────────────────────────────────────────────────────── +echo "==> [2/3] flutter build macos --release (API=$API_URL)" +( cd "$CLIENT" && flutter build macos --release --dart-define=PANGOLIN_API_URL="$API_URL" ) + +APP="$(ls -d "$CLIENT"/build/macos/Build/Products/Release/*.app 2>/dev/null | head -1)" +[ -n "$APP" ] || { echo "✗ 未找到构建产物 .app"; exit 1; } +EXE="$APP/Contents/MacOS/$(basename "$APP" .app)" + +# ── 3. 前台运行(日志直出)──────────────────────────────────────────────────── +echo "==> [3/3] 运行 release 包(前台,日志直出;Ctrl+C 退出)" +echo " app : $APP" +echo " 内核: 客户端会解析到 $SINGBOX(已加进默认查找路径)" +echo " 连上后另开终端验证出口: curl https://api.ipify.org → 期望 ${API_URL#http://}" +echo "------------------------------------------------------------------" +exec "$EXE"