diff --git a/pnpm-install/README.md b/pnpm-install/README.md index 1b65c27..91f11f7 100644 --- a/pnpm-install/README.md +++ b/pnpm-install/README.md @@ -15,7 +15,6 @@ | 参数名 | 描述 | 必需 | 默认值 | | --- | --- | --- | --- | | `cache-prefix` | 缓存 key 前缀 | 否 | `modules` | -| `store-path` | 自定义 pnpm store 路径(默认使用 runner 临时目录) | 否 | `''` | | `force-install` | 是否强制安装(追加 `--force`) | 否 | `false` | | `install-command` | 自定义安装命令,覆盖默认的 `pnpm install` | 否 | `''` | | `install-args` | 附加参数(仅默认命令时生效) | 否 | `''` | @@ -41,18 +40,17 @@ - 默认缓存 pnpm store,命中后执行 `pnpm install --offline --frozen-lockfile`,通常在 10 秒内完成链接。 - 首次执行或 lock 文件变更时执行 `pnpm install --prefer-offline --frozen-lockfile`,完成后写入缓存。 +- 当未显式提供 `cache-hash` 时,会依次使用 `pnpm-lock.yaml`、`package.json` 计算 hash 作为兜底,确保缓存具备基本失效条件。 ## 🔁 缓存路径 -默认缓存路径为 `${{ runner.temp }}/.pnpm-store`。如需与团队现有目录保持一致,可通过 `store-path` 自定义: +Action 会根据以下优先级自动识别 pnpm store: -```yaml -with: - store-path: ~/.cache/pnpm-store - cache-hash: ${{ hashFiles('pnpm-lock.yaml') }} -``` +- 显式的 `PNPM_STORE_DIR` 或 `npm_config_store_dir` 环境变量 +- 项目/全局 `.npmrc` 中的 `store-dir=` 配置(支持相对路径自动展开) +- 若以上均不存在,退回 `${{ runner.temp }}/.pnpm-store` -> 提示:如自定义路径,需确保同一 Runner 不会被多个并发作业共享该目录,以免产生竞争条件。 +解析完成后会打印 `pnpm store path: ...`,并将路径写入环境变量 `PNPM_STORE_DIR` 供后续步骤使用。 ## ⚙️ 进阶配置 diff --git a/pnpm-install/action.yml b/pnpm-install/action.yml index 69a510f..c4384a4 100644 --- a/pnpm-install/action.yml +++ b/pnpm-install/action.yml @@ -10,11 +10,6 @@ inputs: required: false default: 'modules' - store-path: - description: '自定义 pnpm store 缓存路径(默认: runner 临时目录/.pnpm-store)' - required: false - default: '' - force-install: description: '是否强制安装 (true/false)' required: false @@ -78,12 +73,15 @@ runs: env: PNPM_VERSION: ${{ steps.detect.outputs.pnpm-version }} FALLBACK_HASH: ${{ hashFiles('pnpm-lock.yaml') }} + PACKAGE_HASH: ${{ hashFiles('package.json') }} run: | set -euo pipefail if [[ -n "${{ inputs.cache-hash }}" ]]; then CACHE_HASH="${{ inputs.cache-hash }}" elif [[ -n "${FALLBACK_HASH}" ]]; then CACHE_HASH="${FALLBACK_HASH}" + elif [[ -n "${PACKAGE_HASH}" ]]; then + CACHE_HASH="${PACKAGE_HASH}" else CACHE_HASH="" fi @@ -105,13 +103,62 @@ runs: run: | set -euo pipefail DEFAULT_STORE="${RUNNER_TEMP:-$HOME}/.pnpm-store" - if [[ -n "${{ inputs.store-path }}" ]]; then - CACHE_PATH="${{ inputs.store-path }}" - else - CACHE_PATH="$DEFAULT_STORE" + STORE_DIR_CANDIDATE="${PNPM_STORE_DIR:-${npm_config_store_dir:-}}" + + probe_config () { + local file="$1" + if [[ -n "$STORE_DIR_CANDIDATE" || -z "$file" || ! -f "$file" ]]; then + return + fi + local raw + raw=$(grep -E '^[[:space:]]*store-dir[[:space:]]*=' "$file" | tail -n1 | cut -d= -f2-) + if [[ -z "$raw" ]]; then + return + fi + raw=$(echo "$raw" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + if [[ -z "$raw" ]]; then + return + fi + if [[ "$raw" == /* || "$raw" =~ ^[A-Za-z]:[\\/] ]]; then + STORE_DIR_CANDIDATE="$raw" + else + local base + base=$(cd "$(dirname "$file")" && pwd) + STORE_DIR_CANDIDATE="$base/$raw" + fi + } + + probe_config "${NPM_CONFIG_USERCONFIG:-}" + probe_config ".npmrc" + probe_config "$HOME/.npmrc" + + if [[ -z "$STORE_DIR_CANDIDATE" ]]; then + STORE_DIR_CANDIDATE=$(pnpm store path --silent 2>/dev/null || true) + STORE_DIR_CANDIDATE=$(echo "$STORE_DIR_CANDIDATE" | tail -n1 | tr -d '\r') fi - mkdir -p "$CACHE_PATH" - echo "pnpm store path: '$CACHE_PATH'" + + if [[ -z "$STORE_DIR_CANDIDATE" ]]; then + STORE_DIR_CANDIDATE="$DEFAULT_STORE" + fi + + mkdir -p "$STORE_DIR_CANDIDATE" + + case "$STORE_DIR_CANDIDATE" in + /*) + CACHE_PATH="$STORE_DIR_CANDIDATE" + ;; + ~*) + CACHE_PATH="$(eval echo "$STORE_DIR_CANDIDATE")" + ;; + *) + CACHE_PATH="$(cd "$STORE_DIR_CANDIDATE" 2>/dev/null && pwd)" + if [[ -z "$CACHE_PATH" ]]; then + CACHE_PATH="$STORE_DIR_CANDIDATE" + fi + ;; + esac + + echo "pnpm store path: $CACHE_PATH" echo "PNPM_STORE_DIR=${CACHE_PATH}" >> "$GITHUB_ENV" echo "path=${CACHE_PATH}" >> "$GITHUB_OUTPUT" @@ -141,8 +188,7 @@ runs: export PNPM_STORE_DIR="$STORE_DIR" export npm_config_store_dir="$PNPM_STORE_DIR" export PNPM_CONFIG_STORE_DIR="$PNPM_STORE_DIR" - pnpm config set store-dir "$PNPM_STORE_DIR" --location=project || true - pnpm config set store-dir "$PNPM_STORE_DIR" --location=global || true + echo "📦 Using PNPM_STORE_DIR=$PNPM_STORE_DIR" if [[ -n "${{ inputs.install-command }}" ]]; then echo "🔧 使用自定义安装命令: ${{ inputs.install-command }}" eval "${{ inputs.install-command }}"