skillhub/scripts/publish-cli.sh
dongmucat cca6a64d43 fix(cli): add explicit --registry flag to npm publish command
Ensures npm publish uses the correct registry (registry.npmjs.org) even when
global npm config points to a mirror registry (e.g., registry.npmmirror.com).
2026-05-06 17:00:03 +08:00

148 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
CLI_DIR="$REPO_ROOT/cli"
ENV_LOCAL="$CLI_DIR/.env.local"
PACKAGE_JSON="$CLI_DIR/package.json"
log_stage() {
echo "[publish-cli] $1"
}
usage() {
echo "Usage: $0 [patch|minor|major|skip]" >&2
}
confirm() {
local prompt="$1"
local answer
read -r -p "$prompt [y/N]: " answer
[[ "$answer" =~ ^[Yy]$ ]]
}
BUMP_TYPE="${1:-patch}"
if [[ "$BUMP_TYPE" != "patch" && "$BUMP_TYPE" != "minor" && "$BUMP_TYPE" != "major" && "$BUMP_TYPE" != "skip" ]]; then
usage
exit 1
fi
if [[ ! -f "$ENV_LOCAL" ]]; then
echo "cli/.env.local not found" >&2
echo "Copy cli/.env.example to cli/.env.local" >&2
exit 1
fi
log_stage "loading environment"
set -a
# shellcheck disable=SC1090
source "$ENV_LOCAL"
set +a
: "${NPM_REGISTRY:=https://registry.npmjs.org}"
: "${DRY_RUN:=false}"
if [[ -z "${NPM_TOKEN:-}" ]]; then
echo "NPM_TOKEN is required" >&2
exit 1
fi
if [[ -z "${NPM_ORG:-}" ]]; then
echo "NPM_ORG is required" >&2
exit 1
fi
log_stage "validating package metadata"
PACKAGE_NAME="$(node -p "require('$PACKAGE_JSON').name ?? ''")"
PACKAGE_VERSION="$(node -p "require('$PACKAGE_JSON').version ?? ''")"
PACKAGE_ACCESS="$(node -p "require('$PACKAGE_JSON').publishConfig?.access ?? ''")"
if [[ "$PACKAGE_NAME" != "@${NPM_ORG}/"* ]]; then
echo "package name must match @${NPM_ORG}/* (got $PACKAGE_NAME)" >&2
exit 1
fi
if [[ -z "$PACKAGE_VERSION" ]]; then
echo "package version is required" >&2
exit 1
fi
if [[ "$PACKAGE_ACCESS" != "public" ]]; then
echo "publishConfig.access must be public" >&2
exit 1
fi
log_stage "checking git working tree"
if [[ -n "$(git -C "$REPO_ROOT" status --porcelain)" ]]; then
echo "git working tree is not clean" >&2
exit 1
fi
log_stage "running preflight build"
(
cd "$CLI_DIR"
bun run build
)
log_stage "running preflight tests"
(
cd "$CLI_DIR"
bun run test
)
log_stage "running preflight pack"
(
cd "$CLI_DIR"
npm pack --dry-run
)
if [[ "$BUMP_TYPE" != "skip" ]]; then
if ! confirm "Proceed with version bump ($BUMP_TYPE)?"; then
echo "version bump cancelled" >&2
exit 1
fi
log_stage "bumping version ($BUMP_TYPE)"
(
cd "$CLI_DIR"
npm version "$BUMP_TYPE" --no-git-tag-version
)
fi
NEW_VERSION="$(node -p "require('$PACKAGE_JSON').version ?? ''")"
log_stage "ready to publish $PACKAGE_NAME@$NEW_VERSION"
if [[ "$DRY_RUN" == "true" ]]; then
log_stage "DRY_RUN=true, skipping npm publish"
exit 0
fi
if ! confirm "Publish $PACKAGE_NAME@$NEW_VERSION to $NPM_REGISTRY?"; then
echo "publish cancelled" >&2
exit 2
fi
NPM_CONFIG_FILE="$(mktemp)"
cleanup() {
rm -f "$NPM_CONFIG_FILE"
}
trap cleanup EXIT
REGISTRY_HOST="${NPM_REGISTRY#http://}"
REGISTRY_HOST="${REGISTRY_HOST#https://}"
REGISTRY_HOST="${REGISTRY_HOST%/}"
cat >"$NPM_CONFIG_FILE" <<EOF
registry=${NPM_REGISTRY}
//${REGISTRY_HOST}/:_authToken=${NPM_TOKEN}
always-auth=true
EOF
log_stage "publishing package"
(
cd "$CLI_DIR"
NPM_CONFIG_USERCONFIG="$NPM_CONFIG_FILE" npm publish --access public --registry "$NPM_REGISTRY"
)
log_stage "publish completed"