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 语法与构建检查
|
name: Preflight 语法与构建检查
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
# 关键修复:去掉 container.image: node:22-bookworm-slim
|
# 关键修复 1:去掉 container.image: node:22-bookworm-slim
|
||||||
# 原因:Runner 在 Set up job 阶段会先 docker pull 这个镜像,国内连 Docker Hub 被限速会一直卡转圈。
|
# Runner 在 Set up job 阶段会先 docker pull,国内连 Docker Hub 被限速会一直卡转圈。
|
||||||
# 直接在 Runner 宿主机上执行(通常自带 node 20+);为保证 Node 22 一致性,用 actions/setup-node 主动安装。
|
# 关键修复 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:
|
steps:
|
||||||
- name: 安装基础运行依赖(git/curl/ca-certificates,Runner 自带)
|
- name: 安装基础运行依赖(git/curl/ca-certificates/tar/xz-utils,Runner 自带)
|
||||||
run: |
|
run: |
|
||||||
set -euxo pipefail
|
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 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 curl || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends curl ca-certificates)
|
||||||
command -v node && node -v || true
|
command -v tar || (apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends tar)
|
||||||
command -v npm && npm -v || true
|
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 则自动下载)
|
- name: 确保 Node.js 22 可用(npmmirror 优先 / gh-proxy 兜底 / 绝不直连 GitHub)
|
||||||
uses: actions/setup-node@v4
|
run: |
|
||||||
with:
|
set -euxo pipefail
|
||||||
node-version: "22"
|
# 先判断:当前系统 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 可用
|
- name: 校验 Node + npm + git 可用
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
Reference in New Issue
Block a user