Files
xgj/pnpm-install/action.yml

188 lines
6.1 KiB
YAML
Raw 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.

name: 'pnpm依赖安装与缓存'
description: '专注于pnpm的依赖缓存与安装加速重复执行'
branding:
icon: 'package'
color: 'yellow'
inputs:
cache-prefix:
description: '缓存前缀名称'
required: false
default: 'modules'
force-install:
description: '是否强制安装 (true/false)'
required: false
default: 'false'
install-command:
description: '自定义安装命令(若设置则完全覆盖默认命令)'
required: false
default: ''
install-args:
description: '附加到默认安装命令的参数(当未提供 install-command 时生效)'
required: false
default: ''
cache-hash:
description: '缓存hash值推荐使用hashFiles'
required: false
default: ''
clean-project-store:
description: '安装后清理项目根目录的 .pnpm-store (true/false)'
required: false
default: 'false'
outputs:
cache-hit:
description: '是否命中缓存 (true/false)'
value: ${{ steps.cache.outputs.cache-hit }}
cache-key:
description: '使用的缓存key'
value: ${{ steps.cache-key.outputs.key }}
cache-path:
description: '缓存路径(用于调试与复用)'
value: ${{ steps.cache-path.outputs.path }}
runs:
using: 'composite'
steps:
- name: 检查pnpm
id: detect
shell: bash
run: |
if ! command -v pnpm >/dev/null 2>&1; then
echo "pnpm 未安装"
exit 1
fi
VERSION=$(pnpm --version | tr -d '\n')
if [[ -z "$VERSION" ]]; then
echo "无法获取pnpm版本"
exit 1
fi
echo "pnpm-version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "PNPM_VERSION=${VERSION}" >> "$GITHUB_ENV"
- name: 生成缓存key
id: cache-key
shell: bash
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
if [[ -n "$CACHE_HASH" ]]; then
CACHE_HASH_SHORT=$(echo "$CACHE_HASH" | head -c 12)
else
CACHE_HASH_SHORT="no-hash"
fi
PNPM_VERSION="${PNPM_VERSION}"
CACHE_KEY="${{ runner.os }}-pnpm-v${PNPM_VERSION}-store-${{ inputs.cache-prefix }}-${CACHE_HASH_SHORT}"
RESTORE_PREFIX="${{ runner.os }}-pnpm-v${PNPM_VERSION}-store-${{ inputs.cache-prefix }}-"
echo "key=${CACHE_KEY}" >> "$GITHUB_OUTPUT"
echo "restore-prefix=${RESTORE_PREFIX}" >> "$GITHUB_OUTPUT"
echo "hash=${CACHE_HASH}" >> "$GITHUB_OUTPUT"
- name: 确定缓存路径
id: cache-path
shell: bash
run: |
set -euo pipefail
if ! command -v pnpm >/dev/null 2>&1; then
echo "❌ 未找到 pnpm请先通过 pnpm/action-setup 安装" >&2
exit 1
fi
STORE_DIR_CANDIDATE=$(pnpm store path --silent 2>/dev/null || true)
STORE_DIR_CANDIDATE=$(echo "$STORE_DIR_CANDIDATE" | tail -n1 | tr -d '\r')
if [[ -z "$STORE_DIR_CANDIDATE" ]]; then
echo "❌ pnpm store path 未返回有效路径。可在运行前设置 PNPM_STORE_DIR=/path/to/store 或检查 pnpm 配置" >&2
exit 1
fi
echo "pnpm store path: $STORE_DIR_CANDIDATE"
echo "PNPM_STORE_DIR=${STORE_DIR_CANDIDATE}" >> "$GITHUB_ENV"
echo "path=${STORE_DIR_CANDIDATE}" >> "$GITHUB_OUTPUT"
- name: 拉取缓存
id: cache
uses: actions/cache@v4
with:
path: ${{ steps.cache-path.outputs.path }}
key: ${{ steps.cache-key.outputs.key }}
restore-keys: |
${{ steps.cache-key.outputs.restore-prefix }}
- name: 显示缓存状态
shell: bash
run: |
if [[ "${{ steps.cache.outputs.cache-hit }}" == "true" ]]; then
echo "缓存命中"
else
echo "缓存未命中"
fi
- name: 安装依赖
shell: bash
run: |
set -euo pipefail
STORE_DIR="${PNPM_STORE_DIR:-${{ steps.cache-path.outputs.path }}}"
export PNPM_STORE_DIR="$STORE_DIR"
export npm_config_store_dir="$PNPM_STORE_DIR"
export PNPM_CONFIG_STORE_DIR="$PNPM_STORE_DIR"
echo "📦 Using PNPM_STORE_DIR=$PNPM_STORE_DIR"
if [[ -n "${{ inputs.install-command }}" ]]; then
echo "🔧 使用自定义安装命令: ${{ inputs.install-command }}"
eval "${{ inputs.install-command }}"
exit 0
fi
if [[ "${{ steps.cache.outputs.cache-hit }}" == "true" ]]; then
FLAGS=("--offline" "--frozen-lockfile")
else
FLAGS=("--prefer-offline" "--frozen-lockfile")
fi
if [[ "${{ inputs.force-install }}" == "true" ]]; then
FLAGS+=("--force")
fi
INSTALL_ARGS="${{ inputs.install-args }}"
echo "🔧 执行 pnpm install ${FLAGS[*]} ${INSTALL_ARGS}"
if [[ -n "$INSTALL_ARGS" ]]; then
pnpm install "${FLAGS[@]}" $INSTALL_ARGS
else
pnpm install "${FLAGS[@]}"
fi
if [[ "${{ inputs.clean-project-store }}" == "true" && -d ".pnpm-store" && "$(cd "$PNPM_STORE_DIR" 2>/dev/null && pwd)" != "$(cd .pnpm-store 2>/dev/null && pwd)" ]]; then
rm -rf .pnpm-store || true
fi
echo "🧾 git status --short"
CHANGES=$(git status --short || true)
if [[ -n "$CHANGES" ]]; then
echo "$CHANGES"
echo "❌ 安装依赖后检测到工作区存在未提交变更。请检查上述文件,必要时更新配置或在调用前设置 PNPM_STORE_DIR。" >&2
exit 1
else
echo "✅ 工作区保持干净"
fi
- name: 总结
shell: bash
run: |
echo "pnpm版本: $PNPM_VERSION"
echo "缓存命中: ${{ steps.cache.outputs.cache-hit }}"
echo "缓存key: ${{ steps.cache-key.outputs.key }}"