Some checks failed
site-dist-deploy / build-and-deploy (push) Failing after 3s
重构 CI 构建流程,将原有的复杂构建逻辑提取到独立的 ci-build.sh 脚本中 简化 docker.yml 工作流文件,提高可维护性和复用性
153 lines
4.7 KiB
Bash
153 lines
4.7 KiB
Bash
#!/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
|