ci(apt): Runner 自带命令已存在时跳过 apt-get update,避免卡 30-90s

- 改动点: preflight + meta-warmup 两个系统准备 step 都引入 need_cmd/need_pkg 预探测
- 策略: git/curl/tar/xz/ca-certificates 任一缺包才跑一次 apt-get update + 批量 install,全部满足直接跳过
- 同时: apt 源替换前先 grep archive.ubuntu.com / security.ubuntu.com,避免破坏 Runner 已配的国内/公司镜像
This commit is contained in:
2026-09-18 21:36:31 +08:00
parent db685f26ba
commit 90e32ad086
+124 -21
View File
@@ -61,12 +61,55 @@ jobs:
- name: 安装基础依赖 + 确保 Node 22 可用 + 校验 node/git/npm 可用
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 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
command -v node && echo "系统 node: $(node -v)" || echo "系统 node: 未安装"
command -v npm && echo "系统 npm: $(npm -v)" || echo "系统 npm: 未安装"
# 先统一探测:只有当下列命令/包任意一个缺失时,才统一执行 1 次 apt-get update + install
NEED_APT_UPDATE=0
need_cmd() {
local cmd="$1"
if ! command -v "${cmd}" >/dev/null 2>&1; then
NEED_APT_UPDATE=1
return 1
fi
return 0
}
need_pkg() {
local pkg="$1"
if command -v dpkg >/dev/null 2>&1; then
if dpkg -s "${pkg}" >/dev/null 2>&1; then
return 0
fi
NEED_APT_UPDATE=1
return 1
fi
return 0
}
NEED_GIT=0; need_cmd git || NEED_GIT=1
NEED_CURL=0; need_cmd curl || NEED_CURL=1
NEED_CA=0; need_pkg ca-certificates || NEED_CA=1
NEED_TAR=0; need_cmd tar || NEED_TAR=1
NEED_XZ=0; (need_cmd xz || need_cmd unxz) || NEED_XZ=1
APT_MISSING=()
[ "${NEED_GIT}" = "1" ] && APT_MISSING+=("git")
[ "${NEED_CURL}" = "1" ] && APT_MISSING+=("curl")
[ "${NEED_CA}" = "1" ] && APT_MISSING+=("ca-certificates")
[ "${NEED_TAR}" = "1" ] && APT_MISSING+=("tar")
[ "${NEED_XZ}" = "1" ] && APT_MISSING+=("xz-utils")
if [ "${#APT_MISSING[@]}" -gt 0 ]; then
echo "[apt][preflight] 检测到缺包: ${APT_MISSING[*]},执行 1 次 apt-get update + install"
if command -v sudo >/dev/null 2>&1; then
sudo apt-get update -qq 2>/dev/null || apt-get update -qq 2>/dev/null || true
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends "${APT_MISSING[@]}" 2>/dev/null || \
DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends "${APT_MISSING[@]}" 2>/dev/null || true
else
apt-get update -qq 2>/dev/null || true
DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends "${APT_MISSING[@]}" 2>/dev/null || true
fi
else
echo "[apt][preflight] 所有基础命令/包已存在,跳过 apt-get update(节省 30-90s)"
fi
if command -v node >/dev/null 2>&1; then
CUR_NODE_MAJOR="$(node -v | tr -d 'v' | cut -d. -f1 || echo 0)"
@@ -365,32 +408,92 @@ jobs:
steps:
- name: 系统环境准备(Ubuntu 22.04 默认镜像源换清华 + 全局 GitHub gh-proxy)
run: |
set -euxo pipefail
if command -v apt-get >/dev/null 2>&1; then
sudo apt-get update -qq 2>/dev/null || apt-get update -qq 2>/dev/null || true
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends ca-certificates 2>/dev/null || \
DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends ca-certificates 2>/dev/null || true
set -euo pipefail
# 只在真的缺包时才跑 apt-get update(Runner 通常自带 git/curl/ca-certificates/tar/xz,99% 场景直接跳过)
NEED_APT_UPDATE=0
need_cmd() {
local cmd="$1"
if ! command -v "${cmd}" >/dev/null 2>&1; then
NEED_APT_UPDATE=1
return 1
fi
return 0
}
need_pkg() {
local pkg="$1"
if command -v dpkg >/dev/null 2>&1; then
if dpkg -s "${pkg}" >/dev/null 2>&1; then
return 0
fi
NEED_APT_UPDATE=1
return 1
fi
return 0
}
NEED_GIT=0; need_cmd git || NEED_GIT=1
NEED_CURL=0; need_cmd curl || NEED_CURL=1
NEED_CA=0; need_pkg ca-certificates || NEED_CA=1
NEED_TAR=0; need_cmd tar || NEED_TAR=1
NEED_XZ=0; (need_cmd xz || need_cmd unxz) || NEED_XZ=1
APT_MISSING=()
[ "${NEED_GIT}" = "1" ] && APT_MISSING+=("git")
[ "${NEED_CURL}" = "1" ] && APT_MISSING+=("curl")
[ "${NEED_CA}" = "1" ] && APT_MISSING+=("ca-certificates")
[ "${NEED_TAR}" = "1" ] && APT_MISSING+=("tar")
[ "${NEED_XZ}" = "1" ] && APT_MISSING+=("xz-utils")
if [ "${#APT_MISSING[@]}" -gt 0 ]; then
echo "[apt] 检测到缺包: ${APT_MISSING[*]},执行 apt-get update + install"
if command -v sudo >/dev/null 2>&1; then
sudo apt-get update -qq 2>/dev/null || apt-get update -qq 2>/dev/null || true
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends "${APT_MISSING[@]}" 2>/dev/null || \
DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends "${APT_MISSING[@]}" 2>/dev/null || true
else
apt-get update -qq 2>/dev/null || true
DEBIAN_FRONTEND=noninteractive apt-get install -yqq --no-install-recommends "${APT_MISSING[@]}" 2>/dev/null || true
fi
else
echo "[apt] 所有基础命令/包已存在,跳过 apt-get update(节省 30-90s)"
fi
if command -v update-ca-certificates >/dev/null 2>&1; then
sudo update-ca-certificates 2>/dev/null || update-ca-certificates 2>/dev/null || true
fi
# 镜像源替换:只在命中官方 archive.ubuntu.com / security.ubuntu.com 时才 sed,避免破坏 Runner 已配好的公司/国内镜像
APT_SOURCES_HIT=0
if command -v apt-get >/dev/null 2>&1 && [ -f /etc/apt/sources.list ]; then
sudo sed -i \
-e 's|http://archive.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU}"'|g' \
-e 's|http://security.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU_SECURITY}"'|g' \
-e 's|https://archive.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU}"'|g' \
-e 's|https://security.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU_SECURITY}"'|g' \
/etc/apt/sources.list
fi
if command -v apt-get >/dev/null 2>&1 && ls /etc/apt/sources.list.d/*.sources 1>/dev/null 2>&1; then
for f in /etc/apt/sources.list.d/*.sources; do
if grep -qE 'archive\.ubuntu\.com|security\.ubuntu\.com' /etc/apt/sources.list 2>/dev/null; then
APT_SOURCES_HIT=1
sudo sed -i \
-e 's|http://archive.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU}"'|g' \
-e 's|http://security.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU_SECURITY}"'|g' \
-e 's|https://archive.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU}"'|g' \
-e 's|https://security.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU_SECURITY}"'|g' \
"${f}" 2>/dev/null || true
/etc/apt/sources.list
fi
fi
if command -v apt-get >/dev/null 2>&1 && ls /etc/apt/sources.list.d/*.sources 1>/dev/null 2>&1; then
for f in /etc/apt/sources.list.d/*.sources; do
if grep -qE 'archive\.ubuntu\.com|security\.ubuntu\.com' "${f}" 2>/dev/null; then
APT_SOURCES_HIT=1
sudo sed -i \
-e 's|http://archive.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU}"'|g' \
-e 's|http://security.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU_SECURITY}"'|g' \
-e 's|https://archive.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU}"'|g' \
-e 's|https://security.ubuntu.com/ubuntu|'"${APT_MIRROR_UBUNTU_SECURITY}"'|g' \
"${f}" 2>/dev/null || true
fi
done
fi
if [ "${APT_SOURCES_HIT}" = "1" ]; then
echo "[apt] 检测到官方 Ubuntu 源域名,已替换为清华镜像,下次缺包 install 会走国内源"
else
echo "[apt] 未在 sources(.list.d) 中发现官方 archive.ubuntu.com 域名,跳过镜像源替换(保留 Runner 原有配置)"
fi
sudo git config --system url."${GH_PROXY_PREFIX}https://github.com/".insteadOf "https://github.com/" || true
npm config set registry https://registry.npmmirror.com >/dev/null 2>&1 || true