Files
qiming/qiming-vite-plugin-design-mode/scripts/release-sync-npmmirror.sh
2026-06-01 13:43:09 +08:00

199 lines
5.1 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
# -----------------------------------------------------------------------------
# 手动触发 npmmirror 同步(适用于当前 monorepo 的 4 个发布包)。
#
# 目标:
# 1) 发布完成后,主动触发 npmmirror 拉取 npm 官方源的最新包元数据与 tarball
# 2) 可选做只读校验,确认镜像上是否已经可见指定版本
#
# 接口:
# PUT https://registry.npmmirror.com/<包名>/sync
#
# 模式:
# 默认 sync - 对目标包执行 PUT .../sync
# --dry dry - 仅打印将调用的 URL不发请求
# --check check - 不发 PUT仅检查镜像 registry 是否已有该版本
#
# 包列表:
# - 不传包名:使用默认 4 包shared/react/vue/plugin
# - 传包名参数:仅处理传入包名(可多个)
#
# 环境变量:
# NPM_MIRROR_VERSION 目标版本;未设置时读取根 package.json version
# NPM_MIRROR_REGISTRY 镜像 registry默认 https://registry.npmmirror.com
# NPM_MIRROR_RETRIES 失败重试次数;默认 3
# NPM_MIRROR_SLEEP_SECS 重试间隔秒数;默认 2
# -----------------------------------------------------------------------------
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT_DIR"
REGISTRY="${NPM_MIRROR_REGISTRY:-https://registry.npmmirror.com}"
RETRIES="${NPM_MIRROR_RETRIES:-3}"
SLEEP_SECS="${NPM_MIRROR_SLEEP_SECS:-2}"
MODE="sync"
declare -a USER_PACKAGES=()
print_help() {
cat <<'EOF'
用法:
./scripts/release-sync-npmmirror.sh [--dry | --check] [package...]
示例:
./scripts/release-sync-npmmirror.sh
./scripts/release-sync-npmmirror.sh --dry
./scripts/release-sync-npmmirror.sh --check
./scripts/release-sync-npmmirror.sh @xagi/vite-plugin-design-mode
说明:
默认模式会对每个包调用 PUT <registry>/<pkg>/sync
--dry 仅打印将调用的 URL
--check 使用 npm view --registry=<npmmirror> 校验版本是否可见
环境变量:
NPM_MIRROR_VERSION 目标版本(默认读取根 package.json version
NPM_MIRROR_REGISTRY 默认 https://registry.npmmirror.com
NPM_MIRROR_RETRIES 默认 3
NPM_MIRROR_SLEEP_SECS 默认 2
EOF
}
# 参数解析:支持模式参数与可选包名参数混合。
while [[ $# -gt 0 ]]; do
case "$1" in
--dry)
MODE="dry"
shift
;;
--check)
MODE="check"
shift
;;
-h|--help)
print_help
exit 0
;;
--)
# 兼容 pnpm `script -- --flag` 形式:仅丢弃分隔符,后续参数继续按正常规则解析。
shift
;;
-*)
echo "未知参数: $1(支持 --dry / --check / --help" >&2
exit 2
;;
*)
USER_PACKAGES+=("$1")
shift
;;
esac
done
TARGET_VERSION="${NPM_MIRROR_VERSION:-}"
if [[ -z "$TARGET_VERSION" ]]; then
TARGET_VERSION="$(node -pe "require('./package.json').version")"
fi
# 默认发布包列表与 release 脚本保持一致。
declare -a DEFAULT_PACKAGES=(
"@xagi/design-mode-shared"
"@xagi/design-mode-client-react"
"@xagi/design-mode-client-vue"
"@xagi/vite-plugin-design-mode"
)
declare -a PACKAGES=()
if [[ "${#USER_PACKAGES[@]}" -gt 0 ]]; then
PACKAGES=("${USER_PACKAGES[@]}")
else
PACKAGES=("${DEFAULT_PACKAGES[@]}")
fi
echo "版本: ${TARGET_VERSION}"
echo "模式: ${MODE}"
echo "镜像: ${REGISTRY}"
echo "包数: ${#PACKAGES[@]}"
echo "----------"
sync_one() {
local pkg="$1"
local url="${REGISTRY%/}/${pkg}/sync"
local body_file
body_file="$(mktemp)"
local attempt=1
while [[ "$attempt" -le "$RETRIES" ]]; do
if curl -fsS -X PUT "$url" -o "$body_file" 2>/dev/null; then
local body
body="$(tr -d '\n' < "$body_file" || true)"
rm -f "$body_file"
echo "OK ${pkg} (attempt ${attempt}/${RETRIES}) ${body}"
return 0
fi
if [[ "$attempt" -lt "$RETRIES" ]]; then
echo "RETRY ${pkg} (attempt ${attempt}/${RETRIES}), sleep ${SLEEP_SECS}s..."
sleep "$SLEEP_SECS"
fi
attempt=$((attempt + 1))
done
echo "FAIL ${pkg}"
cat "$body_file" 2>/dev/null || true
rm -f "$body_file"
return 1
}
check_one() {
local pkg="$1"
local got
got="$(npm view "${pkg}@${TARGET_VERSION}" version --registry="${REGISTRY}" 2>/dev/null | tr -d '\r\n' || true)"
if [[ "$got" == "$TARGET_VERSION" ]]; then
echo "OK ${pkg}@${TARGET_VERSION}"
return 0
fi
echo "MISS ${pkg}@${TARGET_VERSION} (镜像返回: ${got:-/404})"
return 1
}
FAILED=0
declare -a FAILED_PACKAGES=()
for pkg in "${PACKAGES[@]}"; do
case "$MODE" in
dry)
echo "PUT ${REGISTRY%/}/${pkg}/sync"
;;
sync)
if ! sync_one "$pkg"; then
FAILED=1
FAILED_PACKAGES+=("$pkg")
fi
;;
check)
if ! check_one "$pkg"; then
FAILED=1
FAILED_PACKAGES+=("$pkg")
fi
;;
esac
done
echo "----------"
if [[ "$FAILED" -ne 0 ]]; then
echo "失败包:"
for pkg in "${FAILED_PACKAGES[@]}"; do
echo " - ${pkg}"
done
if [[ "$MODE" == "check" ]]; then
echo "提示: npm 官方可能已发布但镜像尚未同步,先执行 sync 模式后再 check。"
else
echo "提示: 可稍后重试;也可先确认 npm 官方 registry 已存在对应版本。"
fi
exit 1
fi
echo "完成。"