From 1b68108dec2a4ced31f0f76bb315bc43a4531235 Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:28:28 +0800 Subject: [PATCH 1/9] Create build-x64.sh --- scripts/build-x64.sh | 378 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) create mode 100644 scripts/build-x64.sh diff --git a/scripts/build-x64.sh b/scripts/build-x64.sh new file mode 100644 index 0000000..1b2c278 --- /dev/null +++ b/scripts/build-x64.sh @@ -0,0 +1,378 @@ +#!/bin/bash + +# 构建脚本 (x86_64) - 构建后端和前端,自动生成 OTA 包 + +set -euo pipefail + +# 切换到项目根目录 +cd "$(dirname "$0")/.." + +TARGET="x86_64-unknown-linux-musl" + +is_macos() { + [[ "${OSTYPE:-}" == darwin* ]] +} + +is_windows_bash() { + [[ "${OSTYPE:-}" == msys* || "${OSTYPE:-}" == cygwin* || "${OSTYPE:-}" == win32* ]] +} + +require_cmd() { + local cmd="$1" + local hint="${2:-}" + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "❌ 错误: 未找到命令: $cmd" + if [ -n "$hint" ]; then + echo "$hint" + fi + exit 1 + fi +} + +run_sed_in_place() { + local file="$1" + local expression="$2" + + if is_macos; then + sed -i '' "$expression" "$file" + else + sed -i "$expression" "$file" + fi +} + +print_windows_notice() { + if is_windows_bash; then + echo "⚠️ 检测到 Windows Bash 环境。" + echo " 完整 OTA 后端需要 Linux x86_64 musl 工具链。" + echo " 推荐在 WSL2 Ubuntu 中运行: ./scripts/build-x64.sh --no-upx" + echo "" + fi +} + +check_windows_node_lifecycle() { + if is_windows_bash && ! cmd.exe //c node -v >/dev/null 2>&1; then + echo "❌ 错误: 当前 Git Bash 环境下,Node.js 无法被 npm/pnpm 生命周期脚本识别。" + echo "请改用 WSL2 运行完整 OTA 构建,或修正 Git Bash/Windows PATH 后再执行。" + echo "也可以在原生 PowerShell 中单独运行前端构建: pnpm build" + exit 1 + fi +} + +# 解析命令行参数 +BUILD_BACKEND=true +BUILD_FRONTEND=true +USE_UPX=true +SKIP_OTA=false + +for arg in "$@"; do + case $arg in + --backend-only) + BUILD_FRONTEND=false + ;; + --frontend-only) + BUILD_BACKEND=false + ;; + --no-upx) + USE_UPX=false + ;; + --no-ota) + SKIP_OTA=true + ;; + --help|-h) + echo "用法: ./scripts/build-x64.sh [选项]" + echo "" + echo "选项:" + echo " --backend-only 只构建后端" + echo " --frontend-only 只构建前端" + echo " --no-upx 禁用 UPX 压缩 (默认启用)" + echo " --no-ota 跳过 OTA 包生成" + echo " --help, -h 显示帮助信息" + echo "" + echo "示例:" + echo " ./scripts/build-x64.sh # 构建 + UPX + OTA 包" + echo " ./scripts/build-x64.sh --no-upx # 不压缩" + echo " ./scripts/build-x64.sh --no-ota # 不生成 OTA 包" + echo " ./scripts/build-x64.sh --frontend-only # 仅构建前端" + exit 0 + ;; + esac +done + +print_windows_notice + +# ==================== 同步版本号 ==================== +VERSION_FILE="VERSION" +if [ -f "$VERSION_FILE" ]; then + VERSION=$(cat "$VERSION_FILE" | tr -d '[:space:]') +else + VERSION="3.0.0" + echo "⚠️ VERSION 文件不存在,使用默认版本: $VERSION" +fi + +echo "📦 版本号: $VERSION" +echo "📍 目标架构: $TARGET (x86_64/AMD64)" + +require_cmd sed "请安装 sed,或在 WSL2/Git Bash 环境中运行构建脚本。" + +# 更新 package.json 版本号 +if [ -f "frontend/package.json" ]; then + run_sed_in_place "frontend/package.json" "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/" +fi + +# 更新 Cargo.toml 版本号 +if [ -f "backend/Cargo.toml" ]; then + run_sed_in_place "backend/Cargo.toml" "s/^version = \"[^\"]*\"/version = \"$VERSION\"/" +fi + +echo "" + +# ==================== 构建前端 ==================== +if [ "$BUILD_FRONTEND" = true ]; then + echo "🎨 构建前端..." + echo "" + + cd frontend + + require_cmd node "请先安装 Node.js,并确认 node 在当前 Bash 环境的 PATH 中。Windows/Git Bash 下如使用 nvm-windows,请检查 Git Bash 的 PATH;完整 OTA 推荐在 WSL2 中构建。" + check_windows_node_lifecycle + + if [ -f "pnpm-lock.yaml" ]; then + require_cmd pnpm "请先安装 pnpm。推荐: corepack enable && corepack prepare pnpm@9 --activate" + echo "📦 同步前端依赖 (pnpm)..." + pnpm install --frozen-lockfile + pnpm run lint + pnpm exec vite build + else + require_cmd npm "请先安装 Node.js 和 npm。" + echo "📦 同步前端依赖 (npm)..." + if [ -f "package-lock.json" ]; then + npm ci + elif [ ! -d "node_modules" ]; then + npm install + fi + npm run build + fi + + cd .. + + echo "" + echo "✅ 前端构建完成!" + echo "📍 输出目录: frontend/dist/" + echo "" +fi + +# ==================== 构建后端 ==================== +if [ "$BUILD_BACKEND" = true ]; then + echo "🦀 构建后端 ($TARGET)..." + echo "" + + require_cmd cargo "请先安装 Rust 工具链。推荐: rustup + stable toolchain。" + + if command -v rustup >/dev/null 2>&1; then + if ! rustup target list --installed | grep -qx "$TARGET"; then + echo "❌ 错误: Rust target 未安装: $TARGET" + echo "请执行: rustup target add $TARGET" + exit 1 + fi + fi + + # 对于 x86_64-unknown-linux-musl,在 x86_64 本机上可以使用 musl-gcc 编译 + # 非 x86_64 主机(如 ARM)需要交叉编译器 + HOST_ARCH="$(uname -m)" + if [ "$HOST_ARCH" = "x86_64" ] || [ "$HOST_ARCH" = "amd64" ]; then + if ! command -v musl-gcc &> /dev/null; then + echo "❌ 错误: 未找到 musl-gcc" + echo "" + echo "请安装 musl 工具链:" + if is_macos; then + echo " brew install FiloSottile/musl-cross/musl-cross" + else + echo " apt-get install -y musl-tools" + fi + exit 1 + fi + # 本机构建 x86_64 musl,直接用 musl-gcc + export CC_x86_64_unknown_linux_musl=musl-gcc + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc + else + # 交叉编译:非 x86_64 主机需要 x86_64 musl 交叉编译器 + if ! command -v x86_64-unknown-linux-musl-gcc &> /dev/null; then + echo "❌ 错误: 未找到 x86_64-unknown-linux-musl-gcc" + echo "" + echo "当前主机架构: $HOST_ARCH" + echo "需要安装 x86_64 Linux musl 交叉编译工具链。" + echo "" + echo "macOS 可参考:" + echo " brew tap messense/macos-cross-toolchains" + echo " brew install x86_64-unknown-linux-musl" + exit 1 + fi + export CC_x86_64_unknown_linux_musl=x86_64-unknown-linux-musl-gcc + export CXX_x86_64_unknown_linux_musl=x86_64-unknown-linux-musl-g++ + export AR_x86_64_unknown_linux_musl=x86_64-unknown-linux-musl-ar + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-unknown-linux-musl-gcc + fi + + export SQLITE3_STATIC=1 + export LIBSQLITE3_SYS_USE_PKG_CONFIG=0 + + cd backend + + # 构建 + cargo build --release --target "$TARGET" + + cd .. + + BINARY_PATH="backend/target/$TARGET/release/simadmin" + + echo "" + echo "✅ 后端构建完成!" + echo "📍 二进制文件:" + ls -lh "$BINARY_PATH" + + # UPX 压缩 + if [ "$USE_UPX" = true ]; then + echo "" + echo "🗜️ UPX 压缩..." + + if ! command -v upx &> /dev/null; then + echo "⚠️ 未找到 upx,跳过压缩。需要强制压缩时请先安装 upx。" + else + BEFORE_SIZE=$(stat -f%z "$BINARY_PATH" 2>/dev/null || stat -c%s "$BINARY_PATH" 2>/dev/null) + upx --best --lzma "$BINARY_PATH" + AFTER_SIZE=$(stat -f%z "$BINARY_PATH" 2>/dev/null || stat -c%s "$BINARY_PATH" 2>/dev/null) + if command -v bc >/dev/null 2>&1; then + RATIO=$(echo "scale=1; 100 - ($AFTER_SIZE * 100 / $BEFORE_SIZE)" | bc) + echo "压缩完成!节省: ${RATIO}%" + else + echo "压缩完成!" + fi + ls -lh "$BINARY_PATH" + fi + fi + + echo "" + echo "📋 文件信息:" + if command -v file >/dev/null 2>&1; then + file "$BINARY_PATH" + else + echo "未找到 file 命令,跳过文件类型显示。" + fi +fi + +# ==================== 生成 OTA 包 ==================== +if [ "$SKIP_OTA" = false ] && [ "$BUILD_BACKEND" = true ] && [ "$BUILD_FRONTEND" = true ]; then + echo "" + echo "==========================================" + echo " 生成 OTA 更新包 (x86_64)" + echo "==========================================" + echo "" + + BINARY_PATH="backend/target/$TARGET/release/simadmin" + FRONTEND_DIR="frontend/dist" + + # 检查构建产物 + if [ ! -f "$BINARY_PATH" ]; then + echo "跳过 OTA: 后端二进制不存在" + elif [ ! -d "$FRONTEND_DIR" ]; then + echo "跳过 OTA: 前端构建产物不存在" + else + # 获取 Git commit + if command -v git &> /dev/null && [ -d ".git" ]; then + COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") + else + COMMIT="unknown" + fi + + # 构建时间 + BUILD_TIME=$(TZ=Asia/Shanghai date +"%Y-%m-%dT%H:%M:%S+08:00") + + # 目标架构 + ARCH="$TARGET" + + # 创建临时目录 + require_cmd mktemp "请安装 mktemp/coreutils,或在 WSL2/Linux/macOS 中运行构建脚本。" + require_cmd tar "请安装 tar。" + require_cmd find "请安装 findutils。" + require_cmd sort "请安装 coreutils。" + if ! is_macos; then + require_cmd md5sum "请安装 coreutils,确保 md5sum 可用。" + fi + + OTA_TMP=$(mktemp -d) + trap "rm -rf $OTA_TMP" EXIT + + echo "版本: $VERSION" + echo "Commit: $COMMIT" + echo "构建时间: $BUILD_TIME" + echo "架构: $ARCH" + echo "" + + # 复制后端二进制 + echo "复制后端二进制..." + cp "$BINARY_PATH" "$OTA_TMP/simadmin" + chmod 755 "$OTA_TMP/simadmin" + + # 计算二进制 MD5 + if is_macos; then + BINARY_MD5=$(md5 -q "$OTA_TMP/simadmin") + else + BINARY_MD5=$(md5sum "$OTA_TMP/simadmin" | cut -d' ' -f1) + fi + echo " 二进制 MD5: $BINARY_MD5" + + # 复制前端文件 + echo "复制前端文件..." + mkdir -p "$OTA_TMP/www" + cp -r "$FRONTEND_DIR"/* "$OTA_TMP/www/" + + # 计算前端 MD5 + if is_macos; then + FRONTEND_MD5=$(find "$OTA_TMP/www" -type f -exec md5 -q {} \; | sort | tr '\n' '\n' | md5 -q) + else + FRONTEND_MD5=$(find "$OTA_TMP/www" -type f -exec md5sum {} \; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1) + fi + echo " 前端 MD5: $FRONTEND_MD5" + + # 生成 meta.json + cat > "$OTA_TMP/meta.json" << EOF +{ + "version": "$VERSION", + "commit": "$COMMIT", + "build_time": "$BUILD_TIME", + "binary_md5": "$BINARY_MD5", + "frontend_md5": "$FRONTEND_MD5", + "arch": "$ARCH" +} +EOF + + # 创建输出目录 + mkdir -p release + + # 打包 + OTA_FILE="release/simadmin-x64_${VERSION}.tar.gz" + echo "打包 OTA..." + cd "$OTA_TMP" + tar -czf - meta.json simadmin www > "$OLDPWD/$OTA_FILE" + cd "$OLDPWD" + + # 显示结果 + echo "" + echo "OTA 更新包生成完成!" + echo "输出: $OTA_FILE" + ls -lh "$OTA_FILE" + + # 计算包的 MD5 + if is_macos; then + OTA_MD5=$(md5 -q "$OTA_FILE") + else + OTA_MD5=$(md5sum "$OTA_FILE" | cut -d' ' -f1) + fi + echo "OTA 包 MD5: $OTA_MD5" + fi +fi + +echo "" +echo "==========================================" +echo "部署命令: ./scripts/deploy-x64.sh" +echo "==========================================" From 3f634f4a03143bbae93d297ead4750ffdf818aaa Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:28:51 +0800 Subject: [PATCH 2/9] Create deploy-x64.sh --- scripts/deploy-x64.sh | 132 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 scripts/deploy-x64.sh diff --git a/scripts/deploy-x64.sh b/scripts/deploy-x64.sh new file mode 100644 index 0000000..f920dd0 --- /dev/null +++ b/scripts/deploy-x64.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +# 部署脚本 (x86_64) - 通过 ADB 将构建产物部署到目标设备 + +set -e + +# 切换到项目根目录 +cd "$(dirname "$0")/.." + +# 默认配置 +TARGET_PATH="/opt/simadmin" +DEPLOY_BACKEND=true +DEPLOY_FRONTEND=true +RESTART_SERVICE=true + +# 解析命令行参数 +for arg in "$@"; do + case $arg in + --backend-only) + DEPLOY_FRONTEND=false + ;; + --frontend-only) + DEPLOY_BACKEND=false + ;; + --no-restart) + RESTART_SERVICE=false + ;; + --target=*) + TARGET_PATH="${arg#*=}" + ;; + --help|-h) + echo "用法: ./scripts/deploy-x64.sh [选项]" + echo "" + echo "选项:" + echo " --backend-only 只部署后端" + echo " --frontend-only 只部署前端" + echo " --no-restart 不重启服务(默认会停止现有服务)" + echo " --target=PATH 指定目标路径 (默认: /opt/simadmin)" + echo " --help, -h 显示帮助信息" + echo "" + echo "示例:" + echo " ./scripts/deploy-x64.sh # 部署前端和后端" + echo " ./scripts/deploy-x64.sh --backend-only # 只部署后端" + echo " ./scripts/deploy-x64.sh --frontend-only # 只部署前端" + echo " ./scripts/deploy-x64.sh --no-restart # 部署但不停止服务" + echo " ./scripts/deploy-x64.sh --target=/data/app # 部署到指定路径" + exit 0 + ;; + *) + if [[ ! "$arg" =~ ^-- ]]; then + TARGET_PATH="$arg" + fi + ;; + esac +done + +BACKEND_BIN="backend/target/x86_64-unknown-linux-musl/release/simadmin" +FRONTEND_DIR="frontend/dist" + +echo "🚀 通过 ADB 部署到 ${TARGET_PATH} (x86_64)" +echo "" + +if [ "$DEPLOY_BACKEND" = true ] && [ "$DEPLOY_FRONTEND" = true ]; then + echo "📋 部署模式: 前端 + 后端" +elif [ "$DEPLOY_BACKEND" = true ]; then + echo "📋 部署模式: 仅后端" +else + echo "📋 部署模式: 仅前端" +fi +echo "" + +# 检查 ADB +if ! command -v adb &> /dev/null; then + echo "❌ 错误: 未找到 adb 命令" + echo "请安装 Android SDK Platform Tools" + exit 1 +fi + +# 检查 ADB 连接 +if ! adb devices | grep -q "device$"; then + echo "❌ 错误: 未检测到 ADB 设备" + echo "请确保设备已连接并启用 ADB" + exit 1 +fi + +# 检查后端文件 +if [ "$DEPLOY_BACKEND" = true ]; then + if [ ! -f "$BACKEND_BIN" ]; then + echo "❌ 后端二进制不存在,请先运行 ./scripts/build-x64.sh" + exit 1 + fi +fi + +# 检查前端文件 +if [ "$DEPLOY_FRONTEND" = true ]; then + if [ ! -d "$FRONTEND_DIR" ]; then + echo "❌ 前端构建产物不存在,请先运行 ./scripts/build-x64.sh --frontend-only" + exit 1 + fi +fi + +# 停止正在运行的服务(仅在部署后端时) +if [ "$DEPLOY_BACKEND" = true ] && [ "$RESTART_SERVICE" = true ]; then + echo "⏹️ 停止现有服务..." + adb shell "killall simadmin 2>/dev/null || true" +fi + +# 部署后端 +if [ "$DEPLOY_BACKEND" = true ]; then + echo "📦 部署后端..." + adb push "$BACKEND_BIN" "${TARGET_PATH}/simadmin" + adb shell "chmod +x ${TARGET_PATH}/simadmin" + echo "✅ 后端部署完成" +fi + +# 部署前端(先删除旧文件,避免文件损坏问题) +if [ "$DEPLOY_FRONTEND" = true ]; then + echo "📦 部署前端..." + adb shell "rm -rf ${TARGET_PATH}/www && mkdir -p ${TARGET_PATH}/www" + adb push "$FRONTEND_DIR/." "${TARGET_PATH}/www/" + echo "✅ 前端部署完成" +fi + +echo "" +echo "✅ 部署完成!" +echo "" +echo "在设备上运行:" +echo " adb shell" +echo " cd ${TARGET_PATH} && ./simadmin" +echo "" +echo "或直接运行:" +echo " adb shell 'cd ${TARGET_PATH} && ./simadmin'" From 4701739c5d95f1ed12fd111ff8b312460d9d78a7 Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:29:21 +0800 Subject: [PATCH 3/9] Create pack-ota-x64.sh --- scripts/pack-ota-x64.sh | 137 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 scripts/pack-ota-x64.sh diff --git a/scripts/pack-ota-x64.sh b/scripts/pack-ota-x64.sh new file mode 100644 index 0000000..af899fa --- /dev/null +++ b/scripts/pack-ota-x64.sh @@ -0,0 +1,137 @@ +#!/bin/bash + +# 打包 OTA 更新包 (x86_64) +# 输出: release/simadmin-x64_{version}.tar.gz + +set -e + +# 切换到项目根目录 +cd "$(dirname "$0")/.." + +echo "==========================================" +echo " 打包 OTA 更新包 (x86_64)" +echo "==========================================" +echo "" + +# 读取版本号 +VERSION_FILE="VERSION" +if [ -f "$VERSION_FILE" ]; then + VERSION=$(cat "$VERSION_FILE" | tr -d '[:space:]') +else + echo "❌ 错误: VERSION 文件不存在" + exit 1 +fi + +# 获取 Git commit +if command -v git &> /dev/null && [ -d ".git" ]; then + COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") +else + COMMIT="unknown" +fi + +# 构建时间 +BUILD_TIME=$(TZ=Asia/Shanghai date +"%Y-%m-%dT%H:%M:%S+08:00") + +# 目标架构 +ARCH="x86_64-unknown-linux-musl" + +# 检查构建产物 +BINARY_PATH="backend/target/x86_64-unknown-linux-musl/release/simadmin" +FRONTEND_DIR="frontend/dist" + +if [ ! -f "$BINARY_PATH" ]; then + echo "❌ 错误: 后端二进制不存在: $BINARY_PATH" + echo "请先运行: ./scripts/build-x64.sh" + exit 1 +fi + +if [ ! -d "$FRONTEND_DIR" ]; then + echo "❌ 错误: 前端构建产物不存在: $FRONTEND_DIR" + echo "请先运行: ./scripts/build-x64.sh --frontend-only" + exit 1 +fi + +# 创建临时目录 +OTA_TMP=$(mktemp -d) +trap "rm -rf $OTA_TMP" EXIT + +echo "📦 版本: $VERSION" +echo "📝 Commit: $COMMIT" +echo "🕐 构建时间: $BUILD_TIME" +echo "📍 架构: $ARCH" +echo "" + +# 复制后端二进制 +echo "📋 复制后端二进制..." +cp "$BINARY_PATH" "$OTA_TMP/simadmin" +chmod 755 "$OTA_TMP/simadmin" + +# 计算二进制 MD5 +if [[ "$OSTYPE" == "darwin"* ]]; then + BINARY_MD5=$(md5 -q "$OTA_TMP/simadmin") +else + BINARY_MD5=$(md5sum "$OTA_TMP/simadmin" | cut -d' ' -f1) +fi +echo " MD5: $BINARY_MD5" + +# 复制前端文件 +echo "📋 复制前端文件..." +mkdir -p "$OTA_TMP/www" +cp -r "$FRONTEND_DIR"/* "$OTA_TMP/www/" + +# 计算前端 MD5 +echo "📋 计算前端 MD5..." +if [[ "$OSTYPE" == "darwin"* ]]; then + FRONTEND_MD5=$(find "$OTA_TMP/www" -type f -exec md5 -q {} \; | sort | tr '\n' '\n' | md5 -q) +else + FRONTEND_MD5=$(find "$OTA_TMP/www" -type f -exec md5sum {} \; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1) +fi +echo " MD5: $FRONTEND_MD5" + +# 生成 meta.json +echo "📋 生成 meta.json..." +cat > "$OTA_TMP/meta.json" << EOF +{ + "version": "$VERSION", + "commit": "$COMMIT", + "build_time": "$BUILD_TIME", + "binary_md5": "$BINARY_MD5", + "frontend_md5": "$FRONTEND_MD5", + "arch": "$ARCH" +} +EOF + +cat "$OTA_TMP/meta.json" +echo "" + +# 创建输出目录 +mkdir -p release + +# 打包 +OTA_FILE="release/simadmin-x64_${VERSION}.tar.gz" +echo "📦 打包 OTA 更新包..." +cd "$OTA_TMP" +tar -czf - meta.json simadmin www > "$OLDPWD/$OTA_FILE" +cd "$OLDPWD" + +# 显示结果 +echo "" +echo "==========================================" +echo "✅ OTA 更新包打包完成!" +echo "==========================================" +echo "" +echo "📍 输出文件: $OTA_FILE" +ls -lh "$OTA_FILE" +echo "" +echo "📋 包内容:" +tar -tzf "$OTA_FILE" | head -20 +echo "..." +echo "" + +# 计算包的 MD5 +if [[ "$OSTYPE" == "darwin"* ]]; then + OTA_MD5=$(md5 -q "$OTA_FILE") +else + OTA_MD5=$(md5sum "$OTA_FILE" | cut -d' ' -f1) +fi +echo "📝 OTA 包 MD5: $OTA_MD5" From 4ca5167c91891620002cf8ce15fd5ca533152e99 Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:30:41 +0800 Subject: [PATCH 4/9] Create build-lpac-compat-x64.yml --- .github/workflows/build-lpac-compat-x64.yml | 207 ++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 .github/workflows/build-lpac-compat-x64.yml diff --git a/.github/workflows/build-lpac-compat-x64.yml b/.github/workflows/build-lpac-compat-x64.yml new file mode 100644 index 0000000..bb9a3d8 --- /dev/null +++ b/.github/workflows/build-lpac-compat-x64.yml @@ -0,0 +1,207 @@ +name: Build-Lpac-Compat-X64 + +# 从 lpac 官方源码编译兼容老版本 glibc (2.31) 的 x86_64 二进制。 +# 产物上传到 GitHub Release (固定标签为 lpac),供安装脚本和后端一键修复功能使用。 + +on: + schedule: + # 每天凌晨 0:00 自动检查官方是否有更新 + - cron: '0 0 5,20 * *' + workflow_dispatch: + inputs: + lpac_ref: + description: '手动指定官方构建的分支或 Tag (例如: v2.3.0, main)' + required: false + type: string + default: '' + +permissions: + contents: write + +jobs: + build-lpac-compat-x64: + name: Build lpac (glibc 2.31, x86_64) + runs-on: ubuntu-24.04 + + steps: + - name: Checkout SimAdmin (for workflow context) + uses: actions/checkout@v4 + + - name: Check for lpac updates + id: check + run: | + OFFICIAL_TAG=$(curl -s https://api.github.com/repos/estkme-group/lpac/releases/latest | jq -r .tag_name) + echo "Official latest lpac tag: $OFFICIAL_TAG" + + MANUAL_REF="${{ github.event.inputs.lpac_ref }}" + if [ -n "$MANUAL_REF" ]; then + echo "Using manually specified ref: $MANUAL_REF" + echo "should_build=true" >> $GITHUB_OUTPUT + echo "lpac_ref=$MANUAL_REF" >> $GITHUB_OUTPUT + exit 0 + fi + + OUR_MANIFEST=$(curl -sL -f https://github.com/3899/SimAdmin/releases/download/lpac/lpac-x64.json || echo "{}") + OUR_TAG=$(echo "$OUR_MANIFEST" | jq -r '.version // empty' || echo "") + echo "Our current compiled lpac tag: $OUR_TAG" + + if [ "$OFFICIAL_TAG" = "$OUR_TAG" ] && [ -n "$OUR_TAG" ]; then + echo "No new updates found. Skipping build." + echo "should_build=false" >> $GITHUB_OUTPUT + else + echo "New version detected ($OFFICIAL_TAG) or our release is missing. Building..." + echo "should_build=true" >> $GITHUB_OUTPUT + echo "lpac_ref=$OFFICIAL_TAG" >> $GITHUB_OUTPUT + fi + + - name: Build lpac inside Debian 11 container + if: steps.check.outputs.should_build == 'true' + run: | + mkdir -p release + docker run --rm \ + --platform linux/amd64 \ + -v "$GITHUB_WORKSPACE/release:/output" \ + debian:11 bash -c ' + set -eux + + apt-get update + apt-get install -y --no-install-recommends \ + build-essential cmake git ca-certificates zip \ + pkg-config python3 python3-pip ninja-build \ + libcurl4-openssl-dev libglib2.0-dev \ + libpcsclite-dev libgudev-1.0-dev libglib2.0-doc \ + libudev-dev udev + + pip3 install meson + + echo ">>> Building libqmi from source..." + git clone --depth 1 --branch 1.36.0 https://gitlab.freedesktop.org/mobile-broadband/libqmi.git /libqmi-src + cd /libqmi-src + meson setup build \ + --prefix=/usr/local \ + --libdir=lib \ + --buildtype=release \ + -Dcollection=full \ + -Dmbim_qmux=false \ + -Dqrtr=false \ + -Dintrospection=false \ + -Dman=false \ + -Dbash_completion=false \ + -Dqmi_username=root + ninja -C build + ninja -C build install + ldconfig + echo ">>> libqmi installed: $(pkg-config --modversion qmi-glib)" + + echo ">>> Building lpac..." + git clone --depth 1 --branch "$0" https://github.com/estkme-group/lpac /lpac + cd /lpac + + RESOLVED_VER=$(git describe --tags --always || git rev-parse --short HEAD || echo "$0") + echo "$RESOLVED_VER" > /output/resolved_version.txt + + mkdir build && cd build + cmake .. \ + -DCMAKE_BUILD_TYPE=Release \ + -DSTANDALONE_MODE=ON \ + -DLPAC_WITH_APDU_PCSC=OFF \ + -DLPAC_WITH_APDU_AT=ON \ + -DLPAC_WITH_APDU_QMI=ON + make -j$(nproc) + + DESTDIR=/tmp/lpac-install cmake --install . + + BUNDLE_ROOT="/tmp/lpac-bundle" + mkdir -p "$BUNDLE_ROOT" + + LPAC_BIN=$(find /tmp/lpac-install -name lpac -type f | head -1) + if [ -z "$LPAC_BIN" ] || [ ! -f "$LPAC_BIN" ]; then + echo "ERROR: lpac binary not found in /tmp/lpac-install" + ls -laR /tmp/lpac-install/ || true + exit 1 + fi + cp "$LPAC_BIN" "$BUNDLE_ROOT/lpac" + chmod 755 "$BUNDLE_ROOT/lpac" + + mkdir -p "$BUNDLE_ROOT/lib" + QMI_SO=$(find /usr/local/lib -name "libqmi-glib.so.*.*.*" -type f | head -1) + if [ -n "$QMI_SO" ]; then + cp -L "$QMI_SO" "$BUNDLE_ROOT/lib/" + QMI_BASENAME=$(basename "$QMI_SO") + ln -sf "$QMI_BASENAME" "$BUNDLE_ROOT/lib/libqmi-glib.so.5" + ln -sf "$QMI_BASENAME" "$BUNDLE_ROOT/lib/libqmi-glib.so" + fi + + echo "=== Bundle contents ===" + ls -laR "$BUNDLE_ROOT" + ldd "$BUNDLE_ROOT/lpac" || true + + cd "$BUNDLE_ROOT" + zip -r /output/lpac-linux-x86_64-glibc2.31.zip . + + chmod -R 777 /output + echo "✅ Build complete" + ' "${{ steps.check.outputs.lpac_ref }}" + + - name: Verify output + if: steps.check.outputs.should_build == 'true' + run: | + ls -lh release/ + file release/lpac-linux-x86_64-glibc2.31.zip + + - name: Resolve version info + id: resolve_ver + if: steps.check.outputs.should_build == 'true' + run: | + LPAC_VER=$(cat release/resolved_version.txt) + echo "lpac_ver=$LPAC_VER" >> $GITHUB_OUTPUT + + - name: Generate lpac-x64.json manifest + if: steps.check.outputs.should_build == 'true' + run: | + cat > release/lpac-x64.json << MANIFEST + { + "version": "${{ steps.resolve_ver.outputs.lpac_ver }}", + "assets": [ + { + "name": "lpac-linux-x86_64-glibc2.31.zip", + "arch": "x86_64", + "glibc": "2.31", + "description": "lpac for x86_64 built against glibc 2.31 (Debian 11)" + } + ] + } + MANIFEST + + - name: Upload to SimAdmin Release + if: steps.check.outputs.should_build == 'true' + uses: softprops/action-gh-release@v2 + with: + tag_name: lpac + name: eSIM lpac Compatibility Assets + body: | + eSIM lpac compatibility assets for legacy device environments: + * **lpac Source**: `estkme-group/lpac@${{ steps.resolve_ver.outputs.lpac_ver }}` + * **Glibc version**: `2.31` (Debian 11) + * **Architecture**: `aarch64` (ARM64) | `x86_64` (AMD64) + draft: false + prerelease: true + make_latest: false + files: | + release/lpac-linux-x86_64-glibc2.31.zip + release/lpac-x64.json + overwrite_files: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Summary + if: steps.check.outputs.should_build == 'true' + run: | + echo "## 🎉 lpac compat build complete (x86_64)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Item | Value |" >> $GITHUB_STEP_SUMMARY + echo "|------|-------|" >> $GITHUB_STEP_SUMMARY + echo "| lpac source | estkme-group/lpac@${{ steps.resolve_ver.outputs.lpac_ver }} |" >> $GITHUB_STEP_SUMMARY + echo "| Target glibc | 2.31 (Debian 11) |" >> $GITHUB_STEP_SUMMARY + echo "| Architecture | x86_64 (AMD64) |" >> $GITHUB_STEP_SUMMARY + echo "| Attached to Release | lpac |" >> $GITHUB_STEP_SUMMARY From 06a9ea8897f5c8f61b6df631a510d6b74398beef Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:30:58 +0800 Subject: [PATCH 5/9] Create build-ota-package-x64.yml --- .github/workflows/build-ota-package-x64.yml | 348 ++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 .github/workflows/build-ota-package-x64.yml diff --git a/.github/workflows/build-ota-package-x64.yml b/.github/workflows/build-ota-package-x64.yml new file mode 100644 index 0000000..c7d5008 --- /dev/null +++ b/.github/workflows/build-ota-package-x64.yml @@ -0,0 +1,348 @@ +name: Build-OTA-Package-X64 + +on: + workflow_dispatch: + inputs: + version: + description: '版本号(例如:1.0.0)' + required: false + type: string + default: 'auto' + use_upx: + description: 'build with upx' + required: false + type: boolean + default: true + release_type: + description: '发布类型(Release type)' + required: true + type: choice + default: '最新正式版(latest release)' + options: + - '最新正式版(latest release)' + - '预发布版(pre-release)' + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + +permissions: + contents: write + +jobs: + build-ota-x64: + name: Build OTA Package (x86_64) + runs-on: ubuntu-24.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Read VERSION + id: version + env: + INPUT_VERSION: ${{ inputs.version }} + run: | + CURRENT_VERSION=$(cat VERSION | tr -d '[:space:]') + VERSION=$(echo "$INPUT_VERSION" | tr -d '[:space:]') + + if [ -z "$VERSION" ] || [ "$VERSION" = "auto" ]; then + VERSION="$CURRENT_VERSION" + SOURCE="VERSION file" + else + SOURCE="workflow input" + fi + + if [ -z "$VERSION" ]; then + echo "❌ 错误: 版本号不能为空" + exit 1 + fi + + if ! echo "$VERSION" | grep -Eq '^[0-9]+(\.[0-9]+){1,3}([-.][0-9A-Za-z]+)*$'; then + echo "❌ 错误: 版本号格式不合法: $VERSION" + echo "示例: 1.0.0, 1.0.0-beta.1" + exit 1 + fi + + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + echo "version_source=$SOURCE" >> $GITHUB_OUTPUT + echo "📦 当前 VERSION 文件版本: $CURRENT_VERSION" + echo "📦 本次打包版本号: $VERSION ($SOURCE)" + + # ==================== 安装 Rust 工具链 ==================== + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-unknown-linux-musl + + # ==================== 安装编译工具链 ==================== + - name: Install build toolchain + run: | + sudo apt-get update + sudo apt-get install -y musl-tools + musl-gcc --version + + # ==================== 安装 UPX (可选) ==================== + - name: Install UPX + if: inputs.use_upx == true + run: | + sudo apt-get install -y upx-ucl + upx --version + + # ==================== 缓存 Rust 依赖 ==================== + - name: Cache Rust dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + backend/target/ + key: ${{ runner.os }}-x64-musl-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-x64-musl-cargo- + + # ==================== 同步版本号 ==================== + - name: Sync version numbers + run: | + VERSION="${{ steps.version.outputs.version }}" + echo "同步版本号: $VERSION" + + printf "%s\n" "$VERSION" > VERSION + + sed -i "s/^version = \"[^\"]*\"/version = \"$VERSION\"/" backend/Cargo.toml + + sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/" frontend/package.json + + echo "✅ 版本号同步完成" + + # ==================== 构建后端 ==================== + - name: Build backend (x86_64-unknown-linux-musl) + working-directory: backend + run: | + echo "🦀 构建后端 (x86_64-unknown-linux-musl)..." + + export CC_x86_64_unknown_linux_musl=musl-gcc + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc + export SQLITE3_STATIC=1 + export LIBSQLITE3_SYS_USE_PKG_CONFIG=0 + + cargo build --release --target x86_64-unknown-linux-musl + + BINARY_PATH="target/x86_64-unknown-linux-musl/release/simadmin" + + echo "✅ 后端构建完成!" + ls -lh "$BINARY_PATH" + file "$BINARY_PATH" + + # ==================== UPX 压缩 (可选) ==================== + - name: Compress binary with UPX + if: inputs.use_upx == true + run: | + BINARY_PATH="backend/target/x86_64-unknown-linux-musl/release/simadmin" + + echo "🗜️ UPX 压缩中..." + BEFORE_SIZE=$(stat -c%s "$BINARY_PATH") + + upx --best --lzma "$BINARY_PATH" + + AFTER_SIZE=$(stat -c%s "$BINARY_PATH") + RATIO=$(echo "scale=1; 100 - ($AFTER_SIZE * 100 / $BEFORE_SIZE)" | bc) + + echo "✅ 压缩完成!节省: ${RATIO}%" + ls -lh "$BINARY_PATH" + + # ==================== 设置 Node.js 环境 ==================== + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '24' + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Cache pnpm store + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + # ==================== 构建前端 ==================== + - name: Build frontend + working-directory: frontend + run: | + echo "🎨 构建前端..." + pnpm install --frozen-lockfile + pnpm run build + + echo "✅ 前端构建完成!" + ls -lh dist/ + + # ==================== 打包 OTA ==================== + - name: Package OTA + run: | + echo "==========================================" + echo " 生成 OTA 更新包 (x86_64)" + echo "==========================================" + echo "" + + VERSION="${{ steps.version.outputs.version }}" + COMMIT=$(git rev-parse --short HEAD) + BUILD_TIME=$(TZ=Asia/Shanghai date +"%Y-%m-%dT%H:%M:%S+08:00") + ARCH="x86_64-unknown-linux-musl" + + BINARY_PATH="backend/target/x86_64-unknown-linux-musl/release/simadmin" + FRONTEND_DIR="frontend/dist" + + if [ ! -f "$BINARY_PATH" ]; then + echo "❌ 错误: 后端二进制不存在" + exit 1 + fi + + if [ ! -d "$FRONTEND_DIR" ]; then + echo "❌ 错误: 前端构建产物不存在" + exit 1 + fi + + OTA_TMP=$(mktemp -d) + + echo "📦 版本: $VERSION" + echo "📝 Commit: $COMMIT" + echo "🕐 构建时间: $BUILD_TIME" + echo "📍 架构: $ARCH" + echo "" + + echo "📋 复制后端二进制..." + cp "$BINARY_PATH" "$OTA_TMP/simadmin" + chmod 755 "$OTA_TMP/simadmin" + + BINARY_MD5=$(md5sum "$OTA_TMP/simadmin" | cut -d' ' -f1) + echo " MD5: $BINARY_MD5" + + echo "📋 复制前端文件..." + mkdir -p "$OTA_TMP/www" + cp -r "$FRONTEND_DIR"/* "$OTA_TMP/www/" + + echo "📋 计算前端 MD5..." + FRONTEND_MD5=$(find "$OTA_TMP/www" -type f -exec md5sum {} \; | cut -d' ' -f1 | sort | md5sum | cut -d' ' -f1) + echo " MD5: $FRONTEND_MD5" + + echo "📋 生成 meta.json..." + cat > "$OTA_TMP/meta.json" << EOF + { + "version": "$VERSION", + "commit": "$COMMIT", + "build_time": "$BUILD_TIME", + "binary_md5": "$BINARY_MD5", + "frontend_md5": "$FRONTEND_MD5", + "arch": "$ARCH" + } + EOF + + cat "$OTA_TMP/meta.json" + echo "" + + mkdir -p release + + OTA_FILE="release/simadmin-x64.tar.gz" + echo "📦 打包 OTA 更新包..." + cd "$OTA_TMP" + tar -czf "$GITHUB_WORKSPACE/$OTA_FILE" meta.json simadmin www + cd "$GITHUB_WORKSPACE" + + echo "" + echo "==========================================" + echo "✅ OTA 更新包打包完成!" + echo "==========================================" + echo "" + echo "📍 输出文件: $OTA_FILE" + ls -lh "$OTA_FILE" + echo "" + echo "📋 包内容:" + tar -tzf "$OTA_FILE" | head -20 + echo "" + + OTA_MD5=$(md5sum "$OTA_FILE" | cut -d' ' -f1) + OTA_SHA256=$(sha256sum "$OTA_FILE" | cut -d' ' -f1) + echo "📝 OTA 包 MD5: $OTA_MD5" + echo "📝 OTA 包 SHA-256: $OTA_SHA256" + echo "" + + echo "ota_file=$OTA_FILE" >> $GITHUB_OUTPUT + echo "ota_md5=$OTA_MD5" >> $GITHUB_OUTPUT + echo "ota_sha256=$OTA_SHA256" >> $GITHUB_OUTPUT + echo "build_time=$BUILD_TIME" >> $GITHUB_OUTPUT + id: package + + # ==================== 发布 OTA 包为 Release Asset ==================== + - name: Publish OTA package + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ steps.version.outputs.version }} + name: SimAdmin_v${{ steps.version.outputs.version }} + files: | + release/simadmin-x64.tar.gz + overwrite_files: true + generate_release_notes: true + body: | + ## OTA 更新包 (x86_64) + + ### 版本信息 + + - **版本**: ${{ steps.version.outputs.version }} + - **架构**: x86_64-unknown-linux-musl (AMD64) + - **Commit**: ${{ github.sha }} + - **构建时间**: ${{ steps.package.outputs.build_time }} + - **发布类型**: ${{ inputs.release_type }} + - **文件名**: `simadmin-x64.tar.gz` + - **MD5**: `${{ steps.package.outputs.ota_md5 }}` + - **SHA-256**: `${{ steps.package.outputs.ota_sha256 }}` + + ### 安装说明 + + ```bash + # 上传 OTA 包到设备 + curl -X POST http://IP:3000/api/ota/upload \ + -F "file=@simadmin-x64.tar.gz" + + # 开始 OTA 更新 + curl -X POST http://IP:3000/api/ota/apply + ``` + draft: false + prerelease: ${{ inputs.release_type == '预发布版(pre-release)' }} + make_latest: ${{ inputs.release_type == '最新正式版(latest release)' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # ==================== 构建摘要 ==================== + - name: Build Summary + run: | + echo "## 🎉 OTA 包构建完成 (x86_64)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| 项目 | 值 |" >> $GITHUB_STEP_SUMMARY + echo "|------|-----|" >> $GITHUB_STEP_SUMMARY + echo "| VERSION 文件版本 | ${{ steps.version.outputs.current_version }} |" >> $GITHUB_STEP_SUMMARY + echo "| 版本 | ${{ steps.version.outputs.version }} |" >> $GITHUB_STEP_SUMMARY + echo "| 版本来源 | ${{ steps.version.outputs.version_source }} |" >> $GITHUB_STEP_SUMMARY + echo "| 发布类型 | ${{ inputs.release_type }} |" >> $GITHUB_STEP_SUMMARY + echo "| Commit | ${{ github.sha }} |" >> $GITHUB_STEP_SUMMARY + echo "| 架构 | x86_64-unknown-linux-musl (AMD64) |" >> $GITHUB_STEP_SUMMARY + echo "| UPX 压缩 | ${{ inputs.use_upx }} |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### 📦 产物" >> $GITHUB_STEP_SUMMARY + echo "- \`${{ steps.package.outputs.ota_file }}\`" >> $GITHUB_STEP_SUMMARY + echo "- MD5: \`${{ steps.package.outputs.ota_md5 }}\`" >> $GITHUB_STEP_SUMMARY + echo "- SHA-256: \`${{ steps.package.outputs.ota_sha256 }}\`" >> $GITHUB_STEP_SUMMARY From 12b8e09cbf01d5495658190badc14e54b59e807d Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:39:50 +0800 Subject: [PATCH 6/9] Update install_latest.sh --- install_latest.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install_latest.sh b/install_latest.sh index 379b138..4537fc0 100644 --- a/install_latest.sh +++ b/install_latest.sh @@ -2,7 +2,7 @@ set -eu -REPO="${REPO:-3899/SimAdmin}" +REPO="${REPO:-bbvv77/SimAdmin}" INSTALL_DIR="${INSTALL_DIR:-/opt/simadmin}" SERVICE_NAME="${SERVICE_NAME:-simadmin}" VERSION="${VERSION:-latest}" @@ -18,7 +18,7 @@ SIMADMIN_INSTALL_LPAC="${SIMADMIN_INSTALL_LPAC:-1}" LPAC_REPO="${LPAC_REPO:-estkme-group/lpac}" LPAC_RELEASE_BASE_URL="${LPAC_RELEASE_BASE_URL:-https://github.com/${LPAC_REPO}/releases/latest/download}" LPAC_LATEST_RELEASE_URL="${LPAC_LATEST_RELEASE_URL:-https://github.com/${LPAC_REPO}/releases/latest}" -LPAC_COMPAT_RELEASE_BASE_URL="${LPAC_COMPAT_RELEASE_BASE_URL:-https://github.com/3899/SimAdmin/releases/download/lpac}" +LPAC_COMPAT_RELEASE_BASE_URL="${LPAC_COMPAT_RELEASE_BASE_URL:-https://github.com/bbvv77/SimAdmin/releases/download/lpac}" LPAC_COMPAT_MANIFEST_NAME="${LPAC_COMPAT_MANIFEST_NAME:-lpac.json}" LPAC_TARGET_ARCH="${LPAC_TARGET_ARCH:-}" LPAC_TARGET_VERSION="${LPAC_TARGET_VERSION:-}" @@ -510,7 +510,7 @@ lpac_asset_name_from_url() { lpac_url_source() { url="$1" case "$url" in - "$LPAC_COMPAT_RELEASE_BASE_URL"/*|https://github.com/3899/SimAdmin/releases/download/lpac/*) + "$LPAC_COMPAT_RELEASE_BASE_URL"/*|https://github.com/bbvv77/SimAdmin/releases/download/lpac/*) printf '%s\n' "compat" ;; "$LPAC_RELEASE_BASE_URL"/*|https://github.com/"$LPAC_REPO"/releases/latest/download/*|https://github.com/"$LPAC_REPO"/releases/download/*) From 7359e3883f9e4b0972b9d194d30527ff9ed01c6f Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:41:02 +0800 Subject: [PATCH 7/9] Update build-lpac-compat.yml --- .github/workflows/build-lpac-compat.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-lpac-compat.yml b/.github/workflows/build-lpac-compat.yml index 67364a7..6df77fb 100644 --- a/.github/workflows/build-lpac-compat.yml +++ b/.github/workflows/build-lpac-compat.yml @@ -44,7 +44,7 @@ jobs: fi # 3. 读取我们当前打包的版本 (从我们仓库 releases/download/lpac/lpac.json) - OUR_MANIFEST=$(curl -sL -f https://github.com/3899/SimAdmin/releases/download/lpac/lpac.json || echo "{}") + OUR_MANIFEST=$(curl -sL -f https://github.com/bbvv77/SimAdmin/releases/download/lpac/lpac.json || echo "{}") OUR_TAG=$(echo "$OUR_MANIFEST" | jq -r '.version // empty' || echo "") echo "Our current compiled lpac tag: $OUR_TAG" From 29c22c914acb9cd14711090a48f0115f52d189b8 Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Thu, 9 Jul 2026 23:41:26 +0800 Subject: [PATCH 8/9] Update build-lpac-compat-x64.yml --- .github/workflows/build-lpac-compat-x64.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-lpac-compat-x64.yml b/.github/workflows/build-lpac-compat-x64.yml index bb9a3d8..f88ee4f 100644 --- a/.github/workflows/build-lpac-compat-x64.yml +++ b/.github/workflows/build-lpac-compat-x64.yml @@ -41,7 +41,7 @@ jobs: exit 0 fi - OUR_MANIFEST=$(curl -sL -f https://github.com/3899/SimAdmin/releases/download/lpac/lpac-x64.json || echo "{}") + OUR_MANIFEST=$(curl -sL -f https://github.com/bbvv77/SimAdmin/releases/download/lpac/lpac-x64.json || echo "{}") OUR_TAG=$(echo "$OUR_MANIFEST" | jq -r '.version // empty' || echo "") echo "Our current compiled lpac tag: $OUR_TAG" From d944e385aa8762b0b46d1eef55309529a1e47e71 Mon Sep 17 00:00:00 2001 From: bbvv77 Date: Fri, 10 Jul 2026 00:01:00 +0800 Subject: [PATCH 9/9] aarch64/arm64 or x86_64/amd64 --- install_latest.sh | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/install_latest.sh b/install_latest.sh index 4537fc0..74b06d0 100644 --- a/install_latest.sh +++ b/install_latest.sh @@ -97,6 +97,28 @@ read_with_proxies() { return 1 } +detect_device_arch() { + case "$(uname -m)" in + x86_64|amd64) printf 'x86_64' ;; + aarch64|arm64) printf 'aarch64' ;; + *) printf 'unknown' ;; + esac +} + +resolve_asset_name() { + if [ -n "$ASSET_NAME" ]; then + printf '%s\n' "$ASSET_NAME" + return 0 + fi + + arch="$(detect_device_arch)" + case "$arch" in + x86_64) printf 'simadmin-x64.tar.gz' ;; + aarch64) printf 'simadmin.tar.gz' ;; + *) printf 'simadmin.tar.gz' ;; + esac +} + version_to_tag() { case "$1" in v*) printf '%s\n' "$1" ;; @@ -106,7 +128,8 @@ version_to_tag() { asset_url_from_tag() { tag="$1" - printf 'https://github.com/%s/releases/download/%s/simadmin.tar.gz\n' "$REPO" "$tag" + asset_name="$(resolve_asset_name)" + printf 'https://github.com/%s/releases/download/%s/%s\n' "$REPO" "$tag" "$asset_name" } repo_version() { @@ -123,8 +146,9 @@ resolve_asset_url() { return 0 fi + asset_name="$(resolve_asset_name)" if [ "$VERSION" = "latest" ]; then - printf 'https://github.com/%s/releases/latest/download/%s\n' "$REPO" "$ASSET_NAME" + printf 'https://github.com/%s/releases/latest/download/%s\n' "$REPO" "$asset_name" else asset_url_from_tag "$(version_to_tag "$VERSION")" fi