#!/bin/bash set -e # ========================================== # 统一构建脚本 (CI Build Script) # 功能:自动检测环境、安装 Node.js (不依赖系统预装)、构建项目、打包产物 # 解决:Runner 环境缺失 Node/Docker/Python 等工具导致的问题 # ========================================== # 配置节点版本 NODE_VERSION="20.10.0" DIST_FILE="site_dist.tgz" echo ">>> [Init] Starting CI Build Script..." # ---------------------------------------------------------------- # 1. 基础工具检测与安装 (curl, tar, xz) # ---------------------------------------------------------------- ensure_tools() { echo ">>> [Tools] Checking basic tools..." local missing_tools=() for tool in curl tar xz; do if ! command -v "$tool" &> /dev/null; then missing_tools+=("$tool") fi done if [ ${#missing_tools[@]} -eq 0 ]; then echo " All tools present." return 0 fi echo " Missing tools: ${missing_tools[*]}. Attempting installation..." if command -v apk &> /dev/null; then apk add --no-cache curl tar xz elif command -v apt-get &> /dev/null; then apt-get update && apt-get install -y curl tar xz-utils elif command -v yum &> /dev/null; then yum install -y curl tar xz elif command -v dnf &> /dev/null; then dnf install -y curl tar xz elif command -v zypper &> /dev/null; then zypper install -y curl tar xz else echo "!!! Error: Cannot install missing tools. No known package manager found." exit 1 fi } # ---------------------------------------------------------------- # 2. Node.js 独立环境安装 (Binary Mode) # ---------------------------------------------------------------- install_node() { echo ">>> [Node] Setting up Node.js v${NODE_VERSION}..." # 如果已经有可用的 node 环境且版本匹配,则跳过(可选,为了稳健这里强制使用独立环境) # export PATH="$PWD/node_env/bin:$PATH" # 检测架构 local arch=$(uname -m) local node_arch="" case "$arch" in x86_64) node_arch="x64" ;; aarch64) node_arch="arm64" ;; *) echo "!!! Error: Unsupported architecture: $arch"; exit 1 ;; esac # 检测 Libc (glibc vs musl) local libc_type="glibc" if ldd --version 2>&1 | grep -q "musl"; then libc_type="musl" elif [ -f /etc/alpine-release ]; then libc_type="musl" fi echo " Detected System: Linux ${node_arch} (${libc_type})" # 构建下载 URL # Official URL pattern: https://nodejs.org/dist/vX.Y.Z/node-vX.Y.Z-linux-ARCH[-musl].tar.xz local url_suffix="" if [ "$libc_type" == "musl" ]; then url_suffix="-musl" fi local tar_name="node-v${NODE_VERSION}-linux-${node_arch}${url_suffix}.tar.xz" local download_url="https://nodejs.org/dist/v${NODE_VERSION}/${tar_name}" echo " Downloading: ${download_url}" mkdir -p node_env # 下载并解压 if ! curl -fSL "$download_url" -o "$tar_name"; then echo "!!! Error: Failed to download Node.js binary." echo " Please check if version v${NODE_VERSION} supports ${node_arch}-${libc_type}." exit 1 fi echo " Extracting..." tar -xJf "$tar_name" -C node_env --strip-components=1 rm "$tar_name" # 设置环境变量 export PATH="$PWD/node_env/bin:$PATH" if ! command -v node &> /dev/null; then echo "!!! Error: Node.js installation failed. 'node' command not found." exit 1 fi echo " Node version: $(node -v)" echo " Npm version: $(npm -v)" } # ---------------------------------------------------------------- # 3. 项目构建与打包 # ---------------------------------------------------------------- build_project() { echo ">>> [Build] Starting project build..." # 注入环境变量 (从 CI 环境传递) if [ -n "$VITE_APP_BASE_URL" ]; then echo " Setting VITE_APP_BASE_URL=${VITE_APP_BASE_URL}" echo "VITE_APP_BASE_URL=${VITE_APP_BASE_URL}" > .env.prod fi echo " Installing dependencies..." npm ci --quiet echo " Building..." npm run build:prod echo ">>> [Package] Compressing artifacts..." if [ ! -d "dist" ]; then echo "!!! Error: 'dist' directory not found after build." exit 1 fi # 直接打包 dist 目录下的内容,解压时直接释放文件 tar -C dist -czf "$DIST_FILE" . echo " Success! Artifact created: $DIST_FILE" ls -lh "$DIST_FILE" } # ========================================== # Main Execution Flow # ========================================== ensure_tools install_node build_project