name: 'npm依赖安装与缓存' description: '自动缓存和安装npm依赖,支持多种包管理器' branding: icon: 'package' color: 'blue' inputs: package-manager: description: '包管理器类型 (npm, pnpm, yarn)' required: false default: 'npm' cache-prefix: description: '缓存前缀名称' required: false default: 'modules' node-modules-path: description: 'node_modules目录路径' required: false default: 'node_modules' force-install: description: '是否强制安装 (true/false)' required: false default: 'false' enable-git-stash: description: '安装后是否执行git stash (true/false)' required: false default: 'false' install-command: description: '自定义安装命令(可选,会覆盖默认命令)' required: false default: '' cache-hash: description: '缓存hash值(推荐使用hashFiles计算)' required: false default: "" outputs: cache-hit: description: '是否命中缓存 (true/false)' value: ${{ steps.cache.outputs.cache-hit }} cache-key: description: '使用的缓存key' value: ${{ steps.cache-key.outputs.key }} runs: using: 'composite' steps: - name: 生成缓存key id: cache-key shell: bash env: FALLBACK_HASH: ${{ hashFiles('package.json') }} run: | # 确定使用的hash值 if [[ -n "${{ inputs.cache-hash }}" && "${{ inputs.cache-hash }}" != "" ]]; then CACHE_HASH="${{ inputs.cache-hash }}" echo "✅ 使用用户传入的hash值" elif [[ -n "${FALLBACK_HASH}" && "${FALLBACK_HASH}" != "" ]]; then CACHE_HASH="${FALLBACK_HASH}" echo "📝 未提供hash,使用package.json作为fallback" else CACHE_HASH="" echo "⚠️ 警告: 无法获取hash值,使用默认值" fi # 截取hash的前12位 if [[ -n "${CACHE_HASH}" && "${CACHE_HASH}" != "" ]]; then CACHE_HASH_SHORT=$(echo "${CACHE_HASH}" | head -c 12) echo "✅ 成功计算缓存hash: ${CACHE_HASH_SHORT}" else CACHE_HASH_SHORT="no-hash" echo "⚠️ 使用默认hash值: ${CACHE_HASH_SHORT}" fi CACHE_KEY="${{ runner.os }}-${{ inputs.cache-prefix }}-${CACHE_HASH_SHORT}" echo "key=${CACHE_KEY}" >> $GITHUB_OUTPUT echo "使用hash: ${CACHE_HASH}" echo "缓存key: ${CACHE_KEY}" - name: 拉取缓存依赖 id: cache uses: actions/cache@v4 with: path: ${{ inputs.node-modules-path }} key: ${{ steps.cache-key.outputs.key }} restore-keys: | ${{ runner.os }}-${{ inputs.cache-prefix }}- - name: 显示缓存状态 shell: bash run: | if [[ "${{ steps.cache.outputs.cache-hit }}" == "true" ]]; then echo "✅ 缓存命中,跳过依赖安装" else echo "⚠️ 缓存未命中,开始安装依赖" fi - name: 安装依赖 if: steps.cache.outputs.cache-hit != 'true' shell: bash run: | # 如果提供了自定义安装命令,使用自定义命令 if [[ -n "${{ inputs.install-command }}" ]]; then echo "🔧 使用自定义安装命令: ${{ inputs.install-command }}" ${{ inputs.install-command }} else # 根据包管理器选择安装命令 case "${{ inputs.package-manager }}" in "npm") if [[ "${{ inputs.force-install }}" == "true" ]]; then echo "🔧 使用npm强制安装" npm install --force else echo "🔧 使用npm安装" npm install fi ;; "pnpm") if [[ "${{ inputs.force-install }}" == "true" ]]; then echo "🔧 使用pnpm强制安装" pnpm install --force else echo "🔧 使用pnpm安装" pnpm install fi ;; "yarn") if [[ "${{ inputs.force-install }}" == "true" ]]; then echo "🔧 使用yarn强制安装" yarn install --force else echo "🔧 使用yarn安装" yarn install fi ;; *) echo "❌ 不支持的包管理器: ${{ inputs.package-manager }}" exit 1 ;; esac fi echo "✅ 依赖安装完成" - name: 执行Git Stash if: steps.cache.outputs.cache-hit != 'true' && inputs.enable-git-stash == 'true' shell: bash run: | echo "🔄 执行git stash..." git stash echo "✅ git stash完成" - name: 安装总结 shell: bash run: | echo "📦 依赖安装总结:" echo " - 包管理器: ${{ inputs.package-manager }}" echo " - 缓存命中: ${{ steps.cache.outputs.cache-hit }}" echo " - 缓存key: ${{ steps.cache-key.outputs.key }}" if [[ "${{ steps.cache.outputs.cache-hit }}" != "true" ]]; then echo " - 强制安装: ${{ inputs.force-install }}" echo " - Git Stash: ${{ inputs.enable-git-stash }}" fi