Some checks failed
CI / ci (push) Failing after 2s
将部署链路调整为 CI 构建推送镜像、服务器拉取镜像运行,并拆分/复用 Gitea workflow 与公共准备脚本;同时统一 APP_NAME 与端口变量配置,补充 Docker 与 ESLint 相关配置文件以提升可维护性。 Made-with: Cursor
117 lines
3.5 KiB
Bash
117 lines
3.5 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# Reusable bootstrap for Gitea workflows:
|
||
# 1) checkout target commit
|
||
# 2) ensure Node version (install from domestic mirror if missing/mismatch)
|
||
# 3) ensure Yarn is available (and optionally pin version)
|
||
# 通用准备脚本:用于 CI/Deploy 前的代码检出、Node 准备、Yarn 准备。
|
||
|
||
REPO_URL="${1:?repo url required}"
|
||
GIT_SHA="${2:?git sha required}"
|
||
# 优先使用精确版本 NODE_VERSION;未指定时按 NODE_MAJOR 自动解析最新小版本。
|
||
NODE_MAJOR="${NODE_MAJOR:-22}"
|
||
NODE_VERSION="${NODE_VERSION:-}"
|
||
YARN_VERSION="${YARN_VERSION:-stable}"
|
||
# 默认使用国内镜像,减少下载失败概率。
|
||
NODEJS_MIRROR="${NODEJS_MIRROR:-https://npmmirror.com/mirrors/node}"
|
||
NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmmirror.com}"
|
||
# 安装到用户目录,避免依赖 /opt 写权限。
|
||
NODE_INSTALL_ROOT="${NODE_INSTALL_ROOT:-$HOME/.local/node-ci}"
|
||
|
||
resolve_node_version() {
|
||
# 指定了精确版本时,直接使用。
|
||
if [ -n "${NODE_VERSION}" ]; then
|
||
echo "${NODE_VERSION#v}"
|
||
return
|
||
fi
|
||
|
||
# 未指定精确版本时,从镜像索引中选定 NODE_MAJOR 对应的最新版本。
|
||
local resolved
|
||
resolved="$(curl -fsSL "${NODEJS_MIRROR}/index.tab" | awk -F'\t' -v major="${NODE_MAJOR}" '
|
||
NR > 1 && $1 ~ ("^v" major "\\.") { print substr($1, 2); exit }
|
||
')"
|
||
if [ -z "${resolved}" ]; then
|
||
echo "failed to resolve latest Node ${NODE_MAJOR}.x from ${NODEJS_MIRROR}"
|
||
exit 1
|
||
fi
|
||
echo "${resolved}"
|
||
}
|
||
|
||
detect_arch() {
|
||
# 仅支持常见 Linux 架构;其他架构显式失败,避免下载错误包。
|
||
case "$(uname -m)" in
|
||
x86_64) echo "x64" ;;
|
||
aarch64 | arm64) echo "arm64" ;;
|
||
*)
|
||
echo "unsupported architecture: $(uname -m)"
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
install_node() {
|
||
local target_version="$1"
|
||
local arch name url tarball install_dir bindir
|
||
arch="$(detect_arch)"
|
||
name="node-v${target_version}-linux-${arch}"
|
||
url="${NODEJS_MIRROR}/v${target_version}/${name}.tar.xz"
|
||
tarball="/tmp/${name}.tar.xz"
|
||
install_dir="${NODE_INSTALL_ROOT}/${name}"
|
||
bindir="${install_dir}/bin"
|
||
|
||
if [ ! -x "${bindir}/node" ]; then
|
||
# 下载并解压 Node 二进制包到本地缓存目录。
|
||
mkdir -p "${NODE_INSTALL_ROOT}"
|
||
curl -fsSL "${url}" -o "${tarball}"
|
||
tar -xJf "${tarball}" -C "${NODE_INSTALL_ROOT}"
|
||
rm -f "${tarball}"
|
||
fi
|
||
|
||
export PATH="${bindir}:${PATH}"
|
||
}
|
||
|
||
ensure_node() {
|
||
local target_version node_version
|
||
target_version="$(resolve_node_version)"
|
||
|
||
# 版本完全一致则直接复用,避免重复下载。
|
||
if command -v node >/dev/null 2>&1; then
|
||
node_version="$(node -v | sed 's/^v//')"
|
||
if [ "${node_version}" = "${target_version}" ]; then
|
||
return
|
||
fi
|
||
fi
|
||
|
||
install_node "${target_version}"
|
||
|
||
node_version="$(node -v | sed 's/^v//')"
|
||
if [ "${node_version}" != "${target_version}" ]; then
|
||
echo "failed to switch to Node ${target_version}, current=${node_version}"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 首次执行时检出目标提交;已存在仓库则更新并强制切到指定 SHA。
|
||
if [ ! -d .git ]; then
|
||
git clone "${REPO_URL}" .
|
||
fi
|
||
|
||
git fetch --all --tags --prune
|
||
git checkout -f "${GIT_SHA}"
|
||
|
||
ensure_node
|
||
|
||
# Use domestic npm mirror for package-manager metadata/download.
|
||
npm config set registry "${NPM_REGISTRY}" >/dev/null 2>&1 || true
|
||
|
||
if ! command -v yarn >/dev/null 2>&1; then
|
||
# 通过 corepack 激活指定 Yarn 版本。
|
||
corepack enable
|
||
export COREPACK_NPM_REGISTRY="${NPM_REGISTRY}"
|
||
corepack prepare "yarn@${YARN_VERSION}" --activate
|
||
fi
|
||
|
||
echo "Node: $(node -v)"
|
||
echo "Yarn: $(yarn -v)"
|