release: v1.0.15 — QQBot 死锁修复、离线安装包、musl 架构支持

This commit is contained in:
10000ge10000
2026-03-13 00:20:08 +08:00
parent a99283aee2
commit 3aa39512c0
18 changed files with 1870 additions and 170 deletions

221
scripts/upload_openlist.sh Executable file
View File

@@ -0,0 +1,221 @@
#!/bin/sh
# ============================================================================
# OpenList 网盘上传脚本
# 将构建产物上传到 OpenList (AList) 网盘,便于国内用户下载
#
# 用法:
# sh scripts/upload_openlist.sh [dist_dir]
#
# 环境变量 (必须):
# OPENLIST_URL — OpenList 服务地址 (如 https://pan.example.com)
# OPENLIST_USER — 登录用户名
# OPENLIST_PASS — 登录密码
#
# 环境变量 (可选):
# OPENLIST_PATH — 上传根路径 (默认: /Quark)
# OPENLIST_TOKEN — 直接提供 token, 跳过登录
# UPLOAD_MODE — 上传模式: offline / online / auto (默认 auto)
# auto 模式自动检测: 有 *_offline.run 则离线, 有 .run/.ipk 则在线
# ============================================================================
set -e
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
PKG_DIR=$(cd "$SCRIPT_DIR/.." && pwd)
DIST_DIR="${1:-$PKG_DIR/dist}"
case "$DIST_DIR" in
/*) ;;
*) DIST_DIR="$PKG_DIR/$DIST_DIR" ;;
esac
# 检查必要的环境变量
if [ -z "$OPENLIST_URL" ]; then
echo "错误: 请设置 OPENLIST_URL 环境变量"
echo " 例: export OPENLIST_URL=https://pan.example.com"
exit 1
fi
if [ -z "$OPENLIST_TOKEN" ] && { [ -z "$OPENLIST_USER" ] || [ -z "$OPENLIST_PASS" ]; }; then
echo "错误: 请设置登录凭据"
echo " 方式一: export OPENLIST_USER=xxx OPENLIST_PASS=xxx"
echo " 方式二: export OPENLIST_TOKEN=xxx"
exit 1
fi
UPLOAD_ROOT="${OPENLIST_PATH:-/Quark}"
UPLOAD_MODE="${UPLOAD_MODE:-auto}"
PKG_VERSION=$(cat "$PKG_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' || echo "unknown")
# 去除路径末尾的 /
UPLOAD_ROOT="${UPLOAD_ROOT%/}"
# 自动检测上传模式
if [ "$UPLOAD_MODE" = "auto" ]; then
if ls "$DIST_DIR"/*_offline.run >/dev/null 2>&1; then
UPLOAD_MODE="offline"
elif ls "$DIST_DIR"/*.run >/dev/null 2>&1 || ls "$DIST_DIR"/*.ipk >/dev/null 2>&1; then
UPLOAD_MODE="online"
else
echo "错误: 无法自动检测上传模式dist 目录中无可识别文件"
exit 1
fi
fi
# 根据模式设置子目录和文件匹配规则
case "$UPLOAD_MODE" in
offline)
UPLOAD_SUBDIR="openclaw-离线安装"
;;
online)
UPLOAD_SUBDIR="openclaw-在线安装"
;;
*)
echo "错误: 无效的 UPLOAD_MODE: $UPLOAD_MODE (可选: offline / online / auto)"
exit 1
;;
esac
OPENLIST_URL="${OPENLIST_URL%/}"
log_info() { echo " [✓] $1"; }
log_warn() { echo " [!] $1"; }
log_error() { echo " [✗] $1"; }
# ── 获取 Token ──
get_token() {
if [ -n "$OPENLIST_TOKEN" ]; then
echo "$OPENLIST_TOKEN"
return
fi
log_info "正在登录 OpenList..." >&2
local resp
resp=$(curl -s -X POST "${OPENLIST_URL}/api/auth/login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"${OPENLIST_USER}\",\"password\":\"${OPENLIST_PASS}\"}" 2>/dev/null)
local token
# 尝试解析 JSON 响应 (兼容多种 alist 版本)
# alist v3 响应格式: {"code":200,"data":{"token":"xxx"},"message":"success"}
if command -v jq >/dev/null 2>&1; then
token=$(echo "$resp" | jq -r '.data.token // empty' 2>/dev/null)
else
# 无 jq 时用 grep/sed 提取
token=$(echo "$resp" | grep -o '"token":"[^"]*"' | sed 's/"token":"//;s/"//')
fi
if [ -z "$token" ]; then
log_error "登录失败" >&2
echo " 响应: $resp" >&2
exit 1
fi
log_info "登录成功" >&2
echo "$token"
}
# ── 创建远程目录 ──
create_remote_dir() {
local token="$1"
local remote_path="$2"
curl -s -X POST "${OPENLIST_URL}/api/fs/mkdir" \
-H "Authorization: ${token}" \
-H "Content-Type: application/json" \
-d "{\"path\":\"${remote_path}\"}" >/dev/null 2>&1 || true
}
# ── 上传单个文件 ──
upload_file() {
local token="$1"
local local_file="$2"
local remote_path="$3"
local filename=$(basename "$local_file")
local fsize=$(du -h "$local_file" | cut -f1)
echo " 上传: ${filename} (${fsize})..."
local resp
resp=$(curl -s -X PUT "${OPENLIST_URL}/api/fs/put" \
-H "Authorization: ${token}" \
-H "File-Path: ${remote_path}/${filename}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@${local_file}" \
--max-time 3600 2>/dev/null)
# 检查响应
local code=""
if command -v jq >/dev/null 2>&1; then
code=$(echo "$resp" | jq -r '.code // empty' 2>/dev/null)
else
code=$(echo "$resp" | grep -o '"code":[0-9]*' | grep -o '[0-9]*')
fi
if [ "$code" = "200" ]; then
log_info "${filename} 上传成功"
else
log_error "${filename} 上传失败"
echo " 响应: $resp"
fi
}
# ── 主流程 ──
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ 上传到 OpenList 网盘 ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo " 服务地址: ${OPENLIST_URL}"
echo " 上传模式: ${UPLOAD_MODE}"
echo " 上传路径: ${UPLOAD_ROOT}/${UPLOAD_SUBDIR}/v${PKG_VERSION}"
echo " 本地目录: ${DIST_DIR}"
echo ""
# 查找要上传的文件
UPLOAD_FILES=""
case "$UPLOAD_MODE" in
offline)
# 离线包: 仅 *_offline.run 文件
UPLOAD_FILES=$(find "$DIST_DIR" -name "*_offline.run" 2>/dev/null)
;;
online)
# 在线包: .run (非 offline) + .ipk
for f in "$DIST_DIR"/*.run "$DIST_DIR"/*.ipk; do
[ -f "$f" ] || continue
case "$(basename "$f")" in *_offline.run) continue ;; esac
UPLOAD_FILES="$UPLOAD_FILES $f"
done
UPLOAD_FILES=$(echo "$UPLOAD_FILES" | sed 's/^ //')
;;
esac
if [ -z "$UPLOAD_FILES" ]; then
echo "错误: 未找到可上传的文件"
echo " 模式: $UPLOAD_MODE"
echo " 目录: $DIST_DIR"
exit 1
fi
# 获取 token
TOKEN=$(get_token)
# 创建远程目录
REMOTE_DIR="${UPLOAD_ROOT}/${UPLOAD_SUBDIR}/v${PKG_VERSION}"
echo ""
echo "创建远程目录: ${REMOTE_DIR}"
create_remote_dir "$TOKEN" "$REMOTE_DIR"
# 上传文件
echo ""
echo "开始上传..."
UPLOAD_COUNT=0
for f in $UPLOAD_FILES; do
upload_file "$TOKEN" "$f" "$REMOTE_DIR"
UPLOAD_COUNT=$((UPLOAD_COUNT + 1))
done
echo ""
echo "╔══════════════════════════════════════════════════════════════╗"
printf "║ ✅ 上传完成!共 %-2s 个文件 ║\n" "$UPLOAD_COUNT"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "下载地址: ${OPENLIST_URL}${REMOTE_DIR}"