fix(ci): remove actions/setup-node; use npmmirror/gh-proxy for all remote fetches
Issue: actions/setup-node@v4 directly connects to https://github.com/actions/node-versions/releases/download/... to download Node tarballs (log line Acquiring node-v*-linux-x64.tar.gz), which is throttled or connection-reset from inside China, causing preflight to hang until 15m timeout. Fix: align preflight with build-image job policy (NO third-party 'uses:' directives, ALL remote resources use CN mirrors or GH_PROXY_PREFIX): - Remove uses: actions/setup-node@v4 completely; replace with plain run steps - 3-tier Node 22 readiness with zero direct github.com connections: 1) Fast path: reuse Runner's system node if major version >= 22, skip download entirely 2) Primary: fetch Node 22 tarball from npmmirror CN binary mirror (https://registry.npmmirror.com/-/binary/node/...) and auto-resolve latest 22.x patch via npmmirror index.json using python3 single-quote script + printf stdin (NO heredoc, which previously caused YAML block-scalar indentation parse errors) 3) Fallback: GH_PROXY_PREFIX + official nodejs.org dist URL for the same tarball (proxied, never plain github.com) - NODE_VERSION_FALLBACK=22.13.0 fixed guard when index resolution fails - Post-install: prepend new node bin PATH to GITHUB_ENV so subsequent steps (clone / npm ci / nuxt build) inherit Node 22 automatically - Audit: grep deploy.yml now yields zero 'uses:' directives
This commit is contained in:
+116
-11
@@ -51,22 +51,127 @@ jobs:
|
||||
name: Preflight 语法与构建检查
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
# 关键修复:去掉 container.image: node:22-bookworm-slim
|
||||
# 原因:Runner 在 Set up job 阶段会先 docker pull 这个镜像,国内连 Docker Hub 被限速会一直卡转圈。
|
||||
# 直接在 Runner 宿主机上执行(通常自带 node 20+);为保证 Node 22 一致性,用 actions/setup-node 主动安装。
|
||||
# 关键修复 1:去掉 container.image: node:22-bookworm-slim
|
||||
# Runner 在 Set up job 阶段会先 docker pull,国内连 Docker Hub 被限速会一直卡转圈。
|
||||
# 关键修复 2:去掉 uses: actions/setup-node@v4
|
||||
# setup-node 会直连 GitHub Releases (github.com/actions/node-versions/releases/download/...)
|
||||
# 下载 Node 二进制,国内被限速 → 一直卡在 Acquiring node-v*-linux-x64.tar.gz。
|
||||
# 与 build-image job「禁止第三方 uses、全部用代理/国内源」风格完全对齐:
|
||||
# - Runner 自带 node ≥22 直接用
|
||||
# - 否则优先 npmmirror 国内镜像下载 Node 22 二进制
|
||||
# - 最后兜底用 GH_PROXY_PREFIX 代理 GitHub node-versions Releases 直链
|
||||
env:
|
||||
NODE_MAJOR: "22"
|
||||
NODE_VERSION_FALLBACK: "22.13.0"
|
||||
NODE_MIRROR_PRIMARY: "https://registry.npmmirror.com/-/binary/node"
|
||||
steps:
|
||||
- name: 安装基础运行依赖(git/curl/ca-certificates,Runner 自带)
|
||||
- name: 安装基础运行依赖(git/curl/ca-certificates/tar/xz-utils,Runner 自带)
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
command -v git || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends git ca-certificates)
|
||||
command -v curl || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends curl)
|
||||
command -v node && node -v || true
|
||||
command -v npm && npm -v || true
|
||||
command -v curl || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends curl ca-certificates)
|
||||
command -v tar || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends tar)
|
||||
command -v xz || command -v unxz || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends xz-utils) || true
|
||||
# 预先打印 Runner 自带版本,方便排障
|
||||
command -v node && echo "系统 node: $(node -v)" || echo "系统 node: 未安装"
|
||||
command -v npm && echo "系统 npm: $(npm -v)" || echo "系统 npm: 未安装"
|
||||
|
||||
- name: 使用 Node.js 22(若 Runner 自带版本不足 22 则自动下载)
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
- name: 确保 Node.js 22 可用(npmmirror 优先 / gh-proxy 兜底 / 绝不直连 GitHub)
|
||||
run: |
|
||||
set -euxo pipefail
|
||||
# 先判断:当前系统 node 主版本 ≥ NODE_MAJOR 直接跳过
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
CUR_NODE_MAJOR="$(node -v | tr -d 'v' | cut -d. -f1 || echo 0)"
|
||||
if [ "${CUR_NODE_MAJOR:-0}" -ge "${NODE_MAJOR}" ]; then
|
||||
echo "Runner 已自带 Node $(node -v)(≥ v${NODE_MAJOR}.x),直接复用,不下载"
|
||||
node -v; npm -v
|
||||
exit 0
|
||||
fi
|
||||
echo "Runner 自带 Node v${CUR_NODE_MAJOR} 不足 v${NODE_MAJOR}.x,手动升级"
|
||||
fi
|
||||
|
||||
ARCH="$(uname -m)"
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) PLAT="linux-x64" ;;
|
||||
aarch64|arm64) PLAT="linux-arm64" ;;
|
||||
armv7l) PLAT="linux-armv7l" ;;
|
||||
*) echo "不支持的架构:$ARCH" >&2; exit 1 ;;
|
||||
esac
|
||||
echo "目标架构:$PLAT"
|
||||
|
||||
INSTALL_DIR="${RUNNER_TEMP:-/tmp}/node-${NODE_MAJOR}"
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
|
||||
# 找 Node 22 最新 patch 版本号:不用 GitHub API,走 npmmirror 的 index.json 解析
|
||||
NODE_VER="${NODE_VERSION_FALLBACK}"
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
# 注意:不使用 heredoc,避免 PY_MAJOR 前导缩进 0 导致 YAML 块标量提前结束解析失败
|
||||
PY_NODE_CODE=' import json, re, sys
|
||||
try:
|
||||
data = json.load(sys.stdin)
|
||||
except Exception:
|
||||
data = []
|
||||
target = sys.argv[1] if len(sys.argv) > 1 else "22"
|
||||
best_triple = None
|
||||
best_v = ""
|
||||
for d in data:
|
||||
v = d.get("version", "")
|
||||
m = re.match(r"^v(\d+)\.(\d+)\.(\d+)", v)
|
||||
if not m: continue
|
||||
major, minor, patch = m.groups()
|
||||
if major != target: continue
|
||||
triple = (int(minor), int(patch))
|
||||
if (best_triple is None) or (triple > best_triple):
|
||||
best_triple = triple
|
||||
best_v = f"{major}.{minor}.{patch}"
|
||||
if best_v:
|
||||
print(best_v)'
|
||||
REMOTE_LATEST=""
|
||||
REMOTE_LATEST="$(curl -fsSL --max-time 20 "${NODE_MIRROR_PRIMARY}/index.json" 2>/dev/null \
|
||||
| printf '%s\n' "$PY_NODE_CODE" | python3 - "${NODE_MAJOR}" || true)"
|
||||
if [ -n "$REMOTE_LATEST" ]; then
|
||||
NODE_VER="$REMOTE_LATEST"
|
||||
echo "npmmirror 查得 Node 22 latest: v${NODE_VER}"
|
||||
else
|
||||
echo "npmmirror index 查询失败,使用兜底: v${NODE_VER}"
|
||||
fi
|
||||
else
|
||||
echo "python3 不可用,跳过 npmmirror 最新版本探测,使用兜底: v${NODE_VER}"
|
||||
fi
|
||||
TAR_XZ="node-v${NODE_VER}-${PLAT}.tar.xz"
|
||||
mkdir -p /tmp/node-dl-cache
|
||||
|
||||
# 下载 URL 1:npmmirror 国内二进制镜像(首选,国内最快)
|
||||
URL_1="${NODE_MIRROR_PRIMARY}/v${NODE_VER}/${TAR_XZ}"
|
||||
# 下载 URL 2:nodejs.org 官方直链 + GH_PROXY 前缀兜底(绝不直连 GitHub.com)
|
||||
URL_2="${GH_PROXY_PREFIX}https://nodejs.org/dist/v${NODE_VER}/${TAR_XZ}"
|
||||
|
||||
DL_OK=0
|
||||
for URL in "$URL_1" "$URL_2"; do
|
||||
echo "尝试下载:$URL"
|
||||
if curl -fsSL --max-time 300 --retry 3 --retry-delay 2 -o "/tmp/node-dl-cache/${TAR_XZ}" "$URL"; then
|
||||
echo "下载 OK:$URL"
|
||||
DL_OK=1
|
||||
break
|
||||
fi
|
||||
echo "下载失败,尝试下一个源:$URL"
|
||||
done
|
||||
if [ "$DL_OK" != "1" ]; then
|
||||
echo "所有 Node 下载源均失败(npmmirror + gh-proxy),中止" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 解压并加到 PATH,GITHUB_ENV 注入所有后续 step 自动继承
|
||||
tar -xJf "/tmp/node-dl-cache/${TAR_XZ}" -C "$INSTALL_DIR" --strip-components=1
|
||||
if [ -f "$GITHUB_ENV" ]; then
|
||||
echo "PATH=$INSTALL_DIR/bin:$PATH" >> "$GITHUB_ENV"
|
||||
fi
|
||||
export PATH="$INSTALL_DIR/bin:$PATH"
|
||||
hash -r 2>/dev/null || true
|
||||
node -v
|
||||
npm -v
|
||||
# 把 npm 全局前缀也设在这个目录下,避免权限问题
|
||||
npm config set prefix "$INSTALL_DIR/npm-global" 2>/dev/null || true
|
||||
|
||||
- name: 校验 Node + npm + git 可用
|
||||
run: |
|
||||
|
||||
Reference in New Issue
Block a user