cd2304b268
- 将默认 package-name 从 'opencode' 改为 'opencode-ai' - 将 use-taobao-registry 默认值从 true 改为 false - 更新文档中所有相关示例和参数说明 - 优化自定义包名示例说明
296 lines
9.8 KiB
YAML
296 lines
9.8 KiB
YAML
name: 'Setup OpenCode'
|
||
description: '使用 npm 全局安装 OpenCode 并缓存,支持版本检测和自动更新'
|
||
author: 'Your Organization'
|
||
|
||
branding:
|
||
icon: 'code'
|
||
color: 'purple'
|
||
|
||
inputs:
|
||
version:
|
||
description: 'OpenCode 版本号(例如: 1.0.0, latest)'
|
||
required: false
|
||
default: 'latest'
|
||
|
||
package-name:
|
||
description: 'npm 包名'
|
||
required: false
|
||
default: 'opencode-ai'
|
||
|
||
use-taobao-registry:
|
||
description: '使用淘宝 npm 镜像源 (true/false)'
|
||
required: false
|
||
default: 'false'
|
||
|
||
npm-registry:
|
||
description: '自定义 npm 镜像源地址'
|
||
required: false
|
||
default: ''
|
||
|
||
cache-prefix:
|
||
description: '缓存前缀名称'
|
||
required: false
|
||
default: 'opencode-npm'
|
||
|
||
skip-cache:
|
||
description: '跳过缓存,强制重新安装 (true/false)'
|
||
required: false
|
||
default: 'false'
|
||
|
||
outputs:
|
||
version:
|
||
description: '安装的 OpenCode 版本'
|
||
value: ${{ steps.get-version.outputs.version }}
|
||
|
||
cache-hit:
|
||
description: '缓存是否命中 (true/false)'
|
||
value: ${{ steps.cache-restore.outputs.cache-hit }}
|
||
|
||
updated:
|
||
description: '是否执行了更新 (true/false)'
|
||
value: ${{ steps.check-update.outputs.updated }}
|
||
|
||
runs:
|
||
using: 'composite'
|
||
steps:
|
||
- name: 验证输入参数
|
||
shell: bash
|
||
run: |
|
||
echo "🔍 验证输入参数..."
|
||
|
||
if [[ -z "${{ inputs.version }}" ]]; then
|
||
echo "❌ version 参数不能为空"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ -z "${{ inputs.package-name }}" ]]; then
|
||
echo "❌ package-name 参数不能为空"
|
||
exit 1
|
||
fi
|
||
|
||
echo "✅ 输入参数验证通过"
|
||
echo " - npm 包名: ${{ inputs.package-name }}"
|
||
echo " - 版本: ${{ inputs.version }}"
|
||
echo " - 使用淘宝镜像: ${{ inputs.use-taobao-registry }}"
|
||
echo " - 跳过缓存: ${{ inputs.skip-cache }}"
|
||
|
||
- name: 配置 npm 镜像源
|
||
id: setup-registry
|
||
shell: bash
|
||
run: |
|
||
if [[ -n "${{ inputs.npm-registry }}" ]]; then
|
||
echo "🔧 使用自定义 npm 镜像源"
|
||
NPM_REGISTRY="${{ inputs.npm-registry }}"
|
||
echo " - 镜像源: ${NPM_REGISTRY}"
|
||
elif [[ "${{ inputs.use-taobao-registry }}" == "true" ]]; then
|
||
echo "🇨🇳 使用淘宝 npm 镜像源"
|
||
NPM_REGISTRY="https://registry.npmmirror.com"
|
||
echo " - 镜像源: ${NPM_REGISTRY}"
|
||
else
|
||
echo "🌍 使用默认 npm 镜像源"
|
||
NPM_REGISTRY=""
|
||
fi
|
||
|
||
echo "registry=${NPM_REGISTRY}" >> $GITHUB_OUTPUT
|
||
|
||
- name: 获取 npm 路径
|
||
id: npm-paths
|
||
shell: bash
|
||
run: |
|
||
NPM_PREFIX=$(npm config get prefix)
|
||
NPM_GLOBAL_ROOT=$(npm root -g)
|
||
|
||
echo "prefix=${NPM_PREFIX}" >> $GITHUB_OUTPUT
|
||
echo "global-root=${NPM_GLOBAL_ROOT}" >> $GITHUB_OUTPUT
|
||
echo "📁 npm 全局路径: ${NPM_PREFIX}"
|
||
echo "📦 npm 全局包路径: ${NPM_GLOBAL_ROOT}"
|
||
|
||
- name: 解析版本号
|
||
id: resolve-version
|
||
shell: bash
|
||
env:
|
||
NPM_CONFIG_REGISTRY: ${{ steps.setup-registry.outputs.registry }}
|
||
run: |
|
||
VERSION="${{ inputs.version }}"
|
||
PACKAGE="${{ inputs.package-name }}"
|
||
|
||
if [[ "${VERSION}" == "latest" ]]; then
|
||
echo "🔍 获取最新版本号..."
|
||
LATEST_VERSION=$(npm view ${PACKAGE} version 2>/dev/null || echo "")
|
||
|
||
if [[ -n "${LATEST_VERSION}" ]]; then
|
||
VERSION="${LATEST_VERSION}"
|
||
echo "✅ 最新版本: ${VERSION}"
|
||
else
|
||
echo "⚠️ 无法获取最新版本,使用 latest 标签"
|
||
VERSION="latest"
|
||
fi
|
||
fi
|
||
|
||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||
echo "📌 目标版本: ${VERSION}"
|
||
|
||
- name: 生成缓存键
|
||
id: cache-key
|
||
shell: bash
|
||
run: |
|
||
VERSION="${{ steps.resolve-version.outputs.version }}"
|
||
PACKAGE="${{ inputs.package-name }}"
|
||
CACHE_KEY="${{ runner.os }}-${{ inputs.cache-prefix }}-${PACKAGE}-${VERSION}"
|
||
|
||
echo "key=${CACHE_KEY}" >> $GITHUB_OUTPUT
|
||
echo "🔑 缓存键: ${CACHE_KEY}"
|
||
|
||
- name: 恢复缓存
|
||
id: cache-restore
|
||
if: inputs.skip-cache != 'true'
|
||
uses: actions/cache/restore@v4
|
||
with:
|
||
path: |
|
||
~/.npm
|
||
${{ steps.npm-paths.outputs.global-root }}/${{ inputs.package-name }}
|
||
${{ steps.npm-paths.outputs.prefix }}/bin/${{ inputs.package-name }}
|
||
key: ${{ steps.cache-key.outputs.key }}
|
||
restore-keys: |
|
||
${{ runner.os }}-${{ inputs.cache-prefix }}-${{ inputs.package-name }}-
|
||
|
||
- name: 检查已安装版本
|
||
id: check-installed
|
||
shell: bash
|
||
run: |
|
||
PACKAGE="${{ inputs.package-name }}"
|
||
TARGET_VERSION="${{ steps.resolve-version.outputs.version }}"
|
||
NEED_INSTALL="true"
|
||
|
||
if command -v $PACKAGE &> /dev/null; then
|
||
# 使用 JSON 格式获取版本信息,更可靠
|
||
INSTALLED_INFO=$(npm list -g $PACKAGE --json --depth=0 2>/dev/null || echo '{}')
|
||
INSTALLED_VERSION=$(echo "${INSTALLED_INFO}" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4 || echo "unknown")
|
||
|
||
echo "📦 已安装版本: ${INSTALLED_VERSION}"
|
||
echo "🎯 目标版本: ${TARGET_VERSION}"
|
||
|
||
if [[ "${INSTALLED_VERSION}" == "${TARGET_VERSION}" ]]; then
|
||
NEED_INSTALL="false"
|
||
echo "✅ 版本匹配,无需重新安装"
|
||
elif [[ "${INSTALLED_VERSION}" != "unknown" ]]; then
|
||
echo "⚠️ 版本不匹配,需要更新"
|
||
fi
|
||
else
|
||
echo "⚠️ 未安装 ${PACKAGE}"
|
||
fi
|
||
|
||
echo "need-install=${NEED_INSTALL}" >> $GITHUB_OUTPUT
|
||
|
||
- name: 安装 OpenCode
|
||
if: steps.check-installed.outputs.need-install == 'true'
|
||
shell: bash
|
||
env:
|
||
NPM_CONFIG_REGISTRY: ${{ steps.setup-registry.outputs.registry }}
|
||
run: |
|
||
PACKAGE="${{ inputs.package-name }}"
|
||
VERSION="${{ steps.resolve-version.outputs.version }}"
|
||
INSTALL_SPEC="${PACKAGE}@${VERSION}"
|
||
|
||
echo "📥 安装 ${INSTALL_SPEC}..."
|
||
|
||
# 重试机制:最多尝试 3 次
|
||
MAX_RETRIES=3
|
||
RETRY_COUNT=0
|
||
|
||
while [[ ${RETRY_COUNT} -lt ${MAX_RETRIES} ]]; do
|
||
if npm install -g "${INSTALL_SPEC}" --no-audit --no-fund; then
|
||
echo "✅ 安装成功"
|
||
break
|
||
else
|
||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||
if [[ ${RETRY_COUNT} -lt ${MAX_RETRIES} ]]; then
|
||
echo "⚠️ 安装失败,等待 3 秒后重试 (${RETRY_COUNT}/${MAX_RETRIES})..."
|
||
sleep 3
|
||
else
|
||
echo "❌ 安装失败,已重试 ${MAX_RETRIES} 次"
|
||
exit 1
|
||
fi
|
||
fi
|
||
done
|
||
|
||
- name: 验证安装
|
||
id: verify-install
|
||
if: steps.check-installed.outputs.need-install == 'true'
|
||
shell: bash
|
||
run: |
|
||
PACKAGE="${{ inputs.package-name }}"
|
||
|
||
if command -v $PACKAGE &> /dev/null; then
|
||
echo "install-verified=true" >> $GITHUB_OUTPUT
|
||
echo "✅ 安装验证成功"
|
||
else
|
||
echo "install-verified=false" >> $GITHUB_OUTPUT
|
||
echo "❌ 安装验证失败"
|
||
exit 1
|
||
fi
|
||
|
||
- name: 保存缓存
|
||
if: steps.check-installed.outputs.need-install == 'true' && steps.verify-install.outputs.install-verified == 'true' && inputs.skip-cache != 'true'
|
||
uses: actions/cache/save@v4
|
||
with:
|
||
path: |
|
||
~/.npm
|
||
${{ steps.npm-paths.outputs.global-root }}/${{ inputs.package-name }}
|
||
${{ steps.npm-paths.outputs.prefix }}/bin/${{ inputs.package-name }}
|
||
key: ${{ steps.cache-key.outputs.key }}
|
||
|
||
- name: 获取安装版本
|
||
id: get-version
|
||
shell: bash
|
||
run: |
|
||
PACKAGE="${{ inputs.package-name }}"
|
||
|
||
if command -v $PACKAGE &> /dev/null; then
|
||
# 使用 JSON 格式获取版本,更可靠
|
||
INSTALLED_INFO=$(npm list -g $PACKAGE --json --depth=0 2>/dev/null || echo '{}')
|
||
VERSION=$(echo "${INSTALLED_INFO}" | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4 || echo "unknown")
|
||
|
||
if [[ "${VERSION}" == "unknown" ]]; then
|
||
# 备用方案:直接运行命令获取版本
|
||
VERSION=$($PACKAGE --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown")
|
||
fi
|
||
|
||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||
echo "✅ OpenCode 版本: ${VERSION}"
|
||
else
|
||
echo "version=unknown" >> $GITHUB_OUTPUT
|
||
echo "⚠️ 无法获取 OpenCode 版本"
|
||
fi
|
||
|
||
- name: 检查更新状态
|
||
id: check-update
|
||
shell: bash
|
||
run: |
|
||
if [[ "${{ steps.check-installed.outputs.need-install }}" == "true" ]]; then
|
||
echo "updated=true" >> $GITHUB_OUTPUT
|
||
echo "🔄 已安装新版本"
|
||
else
|
||
echo "updated=false" >> $GITHUB_OUTPUT
|
||
echo "📌 使用已安装版本,未执行更新"
|
||
fi
|
||
|
||
- name: 安装总结
|
||
shell: bash
|
||
run: |
|
||
echo "📊 OpenCode 安装总结:"
|
||
echo " - npm 包名: ${{ inputs.package-name }}"
|
||
echo " - 安装版本: ${{ steps.get-version.outputs.version }}"
|
||
echo " - 缓存命中: ${{ steps.cache-restore.outputs.cache-hit }}"
|
||
echo " - 执行更新: ${{ steps.check-update.outputs.updated }}"
|
||
echo " - 缓存键名: ${{ steps.cache-key.outputs.key }}"
|
||
|
||
if [[ "${{ steps.check-update.outputs.updated }}" == "true" ]]; then
|
||
echo " 🔄 已通过 npm 安装新版本"
|
||
else
|
||
echo " ✅ 使用已安装版本,跳过安装"
|
||
fi
|
||
|
||
echo ""
|
||
echo "🎉 OpenCode 已准备就绪!"
|