Skip to content

chore: release v2.0.10 #6

chore: release v2.0.10

chore: release v2.0.10 #6

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: '发布版本 (例如: 1.0.0)'
required: true
type: string
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
id-token: write
steps:
- name: 检出代码
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: 设置 Node.js
uses: actions/setup-node@v5
with:
node-version: '22'
registry-url: 'https://registry.npmjs.org'
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: 获取 pnpm store 目录
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: 设置 pnpm 缓存
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: 安装依赖
run: |
# 尝试使用 frozen lockfile,如果失败则更新 lockfile
pnpm install --frozen-lockfile || {
echo "⚠️ Lockfile 不匹配,正在更新..."
pnpm install --no-frozen-lockfile
}
- name: 获取版本号
id: get_version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
echo "tag_name=v${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
echo "is_manual=true" >> $GITHUB_OUTPUT
else
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
echo "tag_name=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
echo "is_manual=false" >> $GITHUB_OUTPUT
fi
- name: 检查版本是否已存在
id: check_version
run: |
VERSION=${{ steps.get_version.outputs.version }}
# 安全地获取包名和版本信息
if ! PACKAGE_NAME=$(node -p "require('./package.json').name" 2>/dev/null); then
echo "❌ 无法读取 package.json 中的包名"
exit 1
fi
if ! CURRENT_VERSION=$(node -p "require('./package.json').version" 2>/dev/null); then
echo "❌ 无法读取 package.json 中的当前版本"
exit 1
fi
echo "🔍 检查版本信息:"
echo " 目标版本: $VERSION"
echo " 当前版本: $CURRENT_VERSION"
echo " 包名: $PACKAGE_NAME"
echo " 触发方式: ${{ github.event_name }}"
# 检查版本格式
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then
echo "❌ 版本格式不正确: $VERSION"
echo "请使用语义化版本格式,例如: 1.0.0, 1.0.0-beta.1"
exit 1
fi
# 检查版本是否已在npm上发布
echo "🔍 检查 npm 上的版本..."
NPM_VERSION_OUTPUT=$(npm view "$PACKAGE_NAME@$VERSION" version 2>/dev/null || echo "NOT_FOUND")
if [ "$NPM_VERSION_OUTPUT" != "NOT_FOUND" ] && [ -n "$NPM_VERSION_OUTPUT" ]; then
echo "❌ 版本 $VERSION 已存在于 npm 上"
echo "已发布的版本: $NPM_VERSION_OUTPUT"
echo "请使用新的版本号重新发布"
exit 1
fi
echo "✅ 版本 $VERSION 在 npm 上不存在,可以发布"
# 检查标签是否已存在
echo "🔍 检查 git 标签..."
if git tag -l | grep -q "^v$VERSION$"; then
echo "❌ 标签 v$VERSION 已存在"
echo "请使用新的版本号或删除已存在的标签"
exit 1
fi
echo "✅ 标签 v$VERSION 不存在,可以创建"
# 对于手动触发,检查版本关系
if [ "${{ steps.get_version.outputs.is_manual }}" = "true" ]; then
echo "🔍 检查版本关系..."
if [ "$VERSION" = "$CURRENT_VERSION" ]; then
echo "❌ 新版本号不能与当前版本相同"
echo "当前版本: $CURRENT_VERSION"
echo "请使用更高的版本号"
exit 1
fi
# 使用 node 进行语义化版本比较
VERSION_COMPARE=$(node -e "
const semver = require('module').createRequire(import.meta.url)('./package.json').version;
const target = '$VERSION';
const current = '$CURRENT_VERSION';
function parseVersion(v) {
const [main, pre] = v.split('-');
const [major, minor, patch] = main.split('.').map(Number);
return { major, minor, patch, pre: pre || null };
}
function compareVersions(a, b) {
const va = parseVersion(a);
const vb = parseVersion(b);
if (va.major !== vb.major) return va.major - vb.major;
if (va.minor !== vb.minor) return va.minor - vb.minor;
if (va.patch !== vb.patch) return va.patch - vb.patch;
if (va.pre === null && vb.pre === null) return 0;
if (va.pre === null) return 1;
if (vb.pre === null) return -1;
return va.pre.localeCompare(vb.pre);
}
console.log(compareVersions(target, current));
" 2>/dev/null || echo "0")
if [ "$VERSION_COMPARE" -le "0" ]; then
echo "❌ 新版本号必须大于当前版本"
echo "当前版本: $CURRENT_VERSION"
echo "目标版本: $VERSION"
echo "请使用更高的版本号"
exit 1
fi
echo "✅ 版本号检查通过: $VERSION > $CURRENT_VERSION"
fi
echo "✅ 版本 $VERSION 可以发布"
- name: 更新版本号 (手动触发时)
if: github.event_name == 'workflow_dispatch'
run: |
VERSION=${{ steps.get_version.outputs.version }}
echo "📝 更新 package.json 版本号到 $VERSION"
# 更新 package.json 版本号
npm version $VERSION --no-git-tag-version
# 提交版本更新
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add package.json
git commit -m "chore: bump version to $VERSION"
# 创建标签
git tag ${{ steps.get_version.outputs.tag_name }}
echo "✅ 版本号已更新,标签已创建"
- name: 类型检查
run: pnpm run type-check
- name: 运行测试
run: pnpm run test
- name: 构建项目
run: pnpm run build
- name: 包检查
run: pnpm run lint:package
- name: 生成变更日志
id: changelog
run: |
# 获取上一个标签
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -z "$PREV_TAG" ]; then
# 如果没有上一个标签,获取所有提交
CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges)
else
# 获取两个标签之间的提交
CHANGELOG=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
fi
# 保存到文件以避免特殊字符问题
echo "$CHANGELOG" > changelog.txt
echo "changelog_file=changelog.txt" >> $GITHUB_OUTPUT
- name: 发布到 npm
run: |
echo "🚀 开始发布到 npm..."
pnpm publish --no-git-checks
echo "✅ npm 发布成功"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: 推送更改和标签 (手动触发时)
if: github.event_name == 'workflow_dispatch'
run: |
echo "📤 推送更改和标签..."
git push origin HEAD:${{ github.ref_name }}
git push origin ${{ steps.get_version.outputs.tag_name }}
echo "✅ 推送完成"
- name: 创建 GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.get_version.outputs.tag_name }}
release_name: Release ${{ steps.get_version.outputs.tag_name }}
body_path: ${{ steps.changelog.outputs.changelog_file }}
draft: false
prerelease: false
- name: 通知发布成功
run: |
echo "🎉 发布成功!"
echo "📦 版本: ${{ steps.get_version.outputs.version }}"
echo "🏷️ 标签: ${{ steps.get_version.outputs.tag_name }}"
echo "📝 npm: https://www.npmjs.com/package/@winner-fed/cloud-utils"