Spaces:
Sleeping
Sleeping
| : "${REPO_API_URL:=https://api.github.com/repos/caidaoli/CLIProxyAPI/releases/latest}" | |
| : "${RUNTIME_DIR:=/tmp/runtime}" | |
| : "${RELEASES_DIR:=$RUNTIME_DIR/releases}" | |
| : "${CURRENT_LINK:=$RUNTIME_DIR/current}" | |
| : "${CURRENT_TAG_FILE:=$RUNTIME_DIR/current.tag}" | |
| : "${DOWNLOADS_DIR:=$RUNTIME_DIR/downloads}" | |
| : "${SUPERVISOR_CONF:=/etc/supervisord.conf}" | |
| : "${SUPERVISOR_PROGRAM_NAME:=app}" | |
| : "${SUPERVISOR_UPDATER_PROGRAM_NAME:=${SUPERVISOR_PROGRAM_NAME}-updater}" | |
| : "${CURRENT_BINARY_NAME:=app}" | |
| : "${APP_BINARY_NAMES:=}" | |
| log() { | |
| timestamp=$(date '+%Y-%m-%d %H:%M:%S %z') | |
| printf '[%s] %s\n' "$timestamp" "$*" >&2 | |
| } | |
| tag_to_dir_name() { | |
| printf '%s\n' "$1" | tr '/:' '__' | |
| } | |
| release_dir_for_tag() { | |
| printf '%s/%s\n' "$RELEASES_DIR" "$(tag_to_dir_name "$1")" | |
| } | |
| ensure_runtime_dirs() { | |
| mkdir -p "$RUNTIME_DIR" "$RELEASES_DIR" "$DOWNLOADS_DIR" | |
| } | |
| current_tag() { | |
| if [ -f "$CURRENT_TAG_FILE" ]; then | |
| tr -d '\n' < "$CURRENT_TAG_FILE" | |
| fi | |
| } | |
| current_binary_path() { | |
| printf '%s/%s\n' "$CURRENT_LINK" "$CURRENT_BINARY_NAME" | |
| } | |
| fetch_latest_release_info() { | |
| response=$(curl -fsSL "$REPO_API_URL") || return 1 | |
| tag_name=$( | |
| printf '%s\n' "$response" \ | |
| | grep -Eo '"tag_name"[[:space:]]*:[[:space:]]*"[^"]+"' \ | |
| | head -n 1 \ | |
| | cut -d '"' -f 4 \ | |
| || true | |
| ) | |
| asset_url=$( | |
| printf '%s\n' "$response" \ | |
| | grep -Eo '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]*"' \ | |
| | cut -d '"' -f 4 \ | |
| | grep -E '/[^/]*linux[-_]amd64(\.tar\.gz)?$' \ | |
| | head -n 1 \ | |
| || true | |
| ) | |
| if [ -z "$tag_name" ] || [ -z "$asset_url" ]; then | |
| return 1 | |
| fi | |
| printf '%s|%s\n' "$tag_name" "$asset_url" | |
| } | |
| load_latest_release() { | |
| release_info=$(fetch_latest_release_info) || return 1 | |
| LATEST_TAG=${release_info%%|*} | |
| LATEST_ASSET_URL=${release_info#*|} | |
| } | |
| find_release_binary() { | |
| release_dir=$1 | |
| for name in $APP_BINARY_NAMES; do | |
| if [ -f "$release_dir/$name" ]; then | |
| printf '%s\n' "$release_dir/$name" | |
| return 0 | |
| fi | |
| done | |
| for name in $APP_BINARY_NAMES; do | |
| binary_path=$(find "$release_dir" -maxdepth 3 -type f -name "$name" | head -n 1) | |
| if [ -n "$binary_path" ]; then | |
| printf '%s\n' "$binary_path" | |
| return 0 | |
| fi | |
| done | |
| file_list=$(find "$release_dir" -maxdepth 3 -type f ! -name '._*' ! -path '*/__MACOSX/*' | sort) | |
| first_file=$(printf '%s\n' "$file_list" | sed -n '1p') | |
| second_file=$(printf '%s\n' "$file_list" | sed -n '2p') | |
| if [ -n "$first_file" ] && [ -z "$second_file" ]; then | |
| printf '%s\n' "$first_file" | |
| return 0 | |
| fi | |
| return 1 | |
| } | |
| activate_release() { | |
| tag_name=$1 | |
| release_dir=$2 | |
| rm -f "$CURRENT_LINK" | |
| ln -s "$release_dir" "$CURRENT_LINK" | |
| printf '%s\n' "$tag_name" > "$CURRENT_TAG_FILE" | |
| } | |
| extract_release_binary() { | |
| source_dir=$1 | |
| target_path=$2 | |
| binary_path=$(find_release_binary "$source_dir" || true) | |
| if [ -z "$binary_path" ]; then | |
| return 1 | |
| fi | |
| if [ "$binary_path" != "$target_path" ]; then | |
| cp "$binary_path" "$target_path" | |
| fi | |
| chmod +x "$target_path" | |
| } | |
| cleanup_workspace() { | |
| workspace=$1 | |
| if [ -n "$workspace" ] && [ -d "$workspace" ]; then | |
| rm -rf "$workspace" | |
| fi | |
| } | |
| install_release() { | |
| tag_name=$1 | |
| asset_url=$2 | |
| ensure_runtime_dirs | |
| release_dir=$(release_dir_for_tag "$tag_name") | |
| release_binary="$release_dir/$CURRENT_BINARY_NAME" | |
| if [ -x "$release_binary" ]; then | |
| activate_release "$tag_name" "$release_dir" | |
| return 0 | |
| fi | |
| workspace=$(mktemp -d "$RUNTIME_DIR/install.XXXXXX") || return 1 | |
| download_name=$(basename "$asset_url") | |
| if [ -z "$download_name" ] || [ "$download_name" = "/" ] || [ "$download_name" = "." ]; then | |
| download_name="release.asset" | |
| fi | |
| download_path="$DOWNLOADS_DIR/$download_name" | |
| stage_dir="$workspace/stage" | |
| rm -f "$download_path" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| mkdir -p "$stage_dir" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| curl -fsSL "$asset_url" -o "$download_path" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| case "$download_path" in | |
| *.tar.gz) | |
| tar -xzf "$download_path" -C "$stage_dir" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| extract_release_binary "$stage_dir" "$stage_dir/$CURRENT_BINARY_NAME" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| ;; | |
| *) | |
| cp "$download_path" "$stage_dir/$CURRENT_BINARY_NAME" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| chmod +x "$stage_dir/$CURRENT_BINARY_NAME" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| ;; | |
| esac | |
| rm -rf "$release_dir" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| mv "$stage_dir" "$release_dir" || { | |
| cleanup_workspace "$workspace" | |
| return 1 | |
| } | |
| cleanup_workspace "$workspace" | |
| activate_release "$tag_name" "$release_dir" | |
| } | |
| ensure_initial_release() { | |
| if load_latest_release; then | |
| if install_release "$LATEST_TAG" "$LATEST_ASSET_URL"; then | |
| return 0 | |
| fi | |
| log "警告: 安装最新版本失败,尝试使用已有版本继续启动" | |
| fi | |
| [ -x "$(current_binary_path)" ] | |
| } | |
| restart_managed_service() { | |
| supervisorctl -c "$SUPERVISOR_CONF" restart "$SUPERVISOR_PROGRAM_NAME" | |
| } | |
| update_if_needed() { | |
| load_latest_release || { | |
| log "检查最新版本失败" | |
| return 1 | |
| } | |
| installed_tag=$(current_tag) | |
| if [ "$LATEST_TAG" = "$installed_tag" ]; then | |
| log "当前已是最新版本: $LATEST_TAG" | |
| return 0 | |
| fi | |
| log "发现新版本: ${installed_tag:-<none>} -> $LATEST_TAG" | |
| install_release "$LATEST_TAG" "$LATEST_ASSET_URL" || { | |
| log "安装新版本失败: $LATEST_TAG" | |
| return 1 | |
| } | |
| if [ -n "$installed_tag" ]; then | |
| restart_managed_service | |
| fi | |
| } | |