From c039fac36ce903bb386650f2853223ed3d545687 Mon Sep 17 00:00:00 2001 From: Lyda <1829913225@qq.com> Date: Wed, 20 Aug 2025 17:53:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=20Web=20=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=8F=91=E5=B8=83=E6=9E=84=E5=BB=BA=E7=9A=84=20GitHub?= =?UTF-8?q?=20Action=EF=BC=8C=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=96=87=E4=BB=B6=E8=B7=AF=E5=BE=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=8C=E4=BC=98=E5=8C=96=E7=89=88=E6=9C=AC=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A1=AE=E4=BF=9D=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7=E6=A0=BC=E5=BC=8F=E4=B8=80=E8=87=B4=EF=BC=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3=E4=BB=A5=E5=8F=8D=E6=98=A0?= =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD=E5=92=8C=E4=BD=BF=E7=94=A8=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- release-web/README.md | 82 ++++++++-- release-web/action.yml | 56 ++++++- .../examples/custom-version-source.yml | 73 +++++++++ release-web/examples/version-handling.yml | 148 ++++++++++++++++++ test-version-logic.sh | 1 + 5 files changed, 342 insertions(+), 18 deletions(-) create mode 100644 release-web/examples/custom-version-source.yml create mode 100644 release-web/examples/version-handling.yml create mode 100644 test-version-logic.sh diff --git a/release-web/README.md b/release-web/README.md index f3fec01..2a24e9f 100644 --- a/release-web/README.md +++ b/release-web/README.md @@ -2,13 +2,13 @@ [![GitHub](https://img.shields.io/badge/github-actions-blue.svg)](https://github.com/features/actions) -自动化 Web 项目发布流程的 GitHub Action,专注于版本管理和发布核心功能。 +自动化 Web 项目发布流程的 GitHub Action,专注于版本管理和发布核心功能,智能处理各种版本格式。 ## 功能特性 - 🚀 **自动化发布**: 支持任意发布命令进行版本管理和发布 - 🌍 **环境变量支持**: 支持传递任意数量的环境变量给发布命令 -- 📦 **版本信息**: 自动获取和输出版本号信息 +- 📦 **智能版本处理**: 自动获取版本号,确保输出格式一致(无 `v` 前缀) - 🔧 **简洁配置**: 最小化配置,专注于发布核心功能 - ✅ **灵活使用**: 可配置发布命令,适应不同项目需求 @@ -56,12 +56,38 @@ SENTRY_VITE: "true" ``` +### 自定义版本文件路径 + +```yaml +- name: 发布Web项目 + uses: actions/xgj/release-web@main + with: + version-file: "./dist/version.txt" # 自定义版本文件位置 + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} +``` + +### 版本格式处理 + +Action 自动处理各种版本格式,确保输出一致: + +```yaml +# 输入可能的格式: +# - 版本文件: "v1.2.3" 或 "1.2.3" +# - Git tag: "v1.2.3" 或 "1.2.3" +# - package.json: "v1.2.3" 或 "1.2.3" +# - 提交信息: "release: v1.2.3" 或 "release: 1.2.3" + +# 输出始终为: "1.2.3" (不含 v 前缀) +``` + ## 输入参数 | 参数名 | 描述 | 必需 | 默认值 | | ----------------- | ------------------------- | ---- | --------------------------------- | | `release-command` | 发布命令 | ❌ | `npm run release -- --release -V` | | `node-debug` | 是否启用 Node.js 调试模式 | ❌ | `false` | +| `version-file` | 自定义版本文件路径 | ❌ | `/tmp/last-version` | ## 环境变量支持 @@ -187,17 +213,22 @@ steps: ## 工作流程 1. **发布构建**: 执行指定的发布命令进行版本发布 -2. **获取版本**: 从 `/tmp/last-version` 读取新版本号 +2. **智能版本获取**: 通过多种方法自动获取版本号 + - 优先从版本文件读取(`/tmp/last-version` 或自定义路径) + - 回退到最新 git tag(自动去除 `v` 前缀) + - 回退到 `package.json` 中的版本 + - 最后尝试从提交信息解析(支持 `v1.2.3` 和 `1.2.3` 格式) + - **所有方法都确保输出不包含 `v` 前缀** 3. **发布总结**: 输出发布信息和结果 ## 依赖要求 ### 项目要求 -- 包含 `package.json` 文件 +- 包含 `package.json` 文件(用于版本回退) - 配置了发布工具(如 `release-it`) - 包含发布脚本(如 `npm run release`) -- 发布命令能够生成版本文件到 `/tmp/last-version` +- 推荐发布命令生成版本文件到 `/tmp/last-version`(或自定义路径) ### 环境依赖 @@ -269,19 +300,44 @@ Action 会在以下情况报错并退出: ### 常见问题 -### Q: 版本文件不存在错误 +### Q: 无法获取版本信息 ```bash -❌ 错误: 版本文件 /tmp/last-version 不存在 +❌ 错误: 无法获取版本信息 ``` -A: 检查 `release-it` 配置是否包含创建版本文件的 hook: +A: Action 会按优先级尝试多种方法获取版本: -```javascript -hooks: { - 'before:release': ['echo \'${version}\' > /tmp/last-version'] -} -``` +1. **版本文件** (推荐):确保发布命令创建版本文件 + + ```javascript + // .release-it.js + hooks: { + 'before:release': ['echo \'${version}\' > /tmp/last-version'] + } + ``` + +2. **Git Tags**:确保发布过程创建了 git tag + + ```bash + git tag v1.2.3 + ``` + +3. **package.json**:确保 package.json 包含有效的 version 字段 + + ```json + { + "version": "1.2.3" + } + ``` + +4. **提交信息**:在提交信息中包含版本号 + + ```bash + git commit -m "release: 1.2.3" + # 或者 + git commit -m "release: v1.2.3" + ``` ### Q: Gitea Token 权限不足 diff --git a/release-web/action.yml b/release-web/action.yml index 7a36410..d58452e 100644 --- a/release-web/action.yml +++ b/release-web/action.yml @@ -11,11 +11,16 @@ inputs: description: '发布命令,例如 npm run release -- --release -V' required: false default: 'npm run release -- --release -V' - + node-debug: description: '是否启用Node.js调试模式 (true/false)' required: false default: 'false' + + version-file: + description: '自定义版本文件路径,默认为 /tmp/last-version' + required: false + default: '/tmp/last-version' outputs: version: @@ -44,16 +49,57 @@ runs: shell: bash run: | echo "📝 获取版本信息..." + VERSION="" - if [[ ! -f "/tmp/last-version" ]]; then - echo "❌ 错误: 版本文件 /tmp/last-version 不存在" - echo "请确保发布命令正确执行并生成了版本文件" + # 方法1: 从指定版本文件读取(优先级最高) + if [[ -f "${{ inputs.version-file }}" ]]; then + VERSION=$(cat "${{ inputs.version-file }}" | tr -d ' \n\r' | sed 's/^v//') + echo "✅ 从版本文件获取: $VERSION" + # 方法2: 从最新的 git tag 获取 + elif git describe --tags --abbrev=0 2>/dev/null; then + VERSION=$(git describe --tags --abbrev=0 | tr -d ' \n\r' | sed 's/^v//') + echo "✅ 从 git tag 获取: $VERSION" + # 方法3: 从 package.json 获取 + elif [[ -f "package.json" ]] && command -v node >/dev/null; then + VERSION=$(node -p "require('./package.json').version" 2>/dev/null | tr -d ' \n\r' | sed 's/^v//') + if [[ -n "$VERSION" && "$VERSION" != "undefined" ]]; then + echo "✅ 从 package.json 获取: $VERSION" + else + VERSION="" + fi + fi + + # 如果所有方法都失败,尝试解析发布命令输出 + if [[ -z "$VERSION" ]]; then + echo "⚠️ 无法通过常规方法获取版本,尝试解析最近的提交信息..." + # 尝试从最近的提交消息中解析版本(如 "release: 1.2.3" 或 "release: v1.2.3" 格式) + COMMIT_VERSION=$(git log -1 --pretty=format:"%s" | grep -oE 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -1 | sed 's/^v//') + if [[ -n "$COMMIT_VERSION" ]]; then + VERSION="$COMMIT_VERSION" + echo "✅ 从提交信息获取: $VERSION" + fi + fi + + # 最终检查和清理版本号 + if [[ -z "$VERSION" ]]; then + echo "❌ 错误: 无法获取版本信息" + echo "请确保:" + echo " 1. 发布命令生成 /tmp/last-version 文件,或" + echo " 2. 存在有效的 git tag,或" + echo " 3. package.json 包含 version 字段,或" + echo " 4. 提交信息包含版本号" exit 1 fi - VERSION=$(cat /tmp/last-version) + # 确保版本号格式正确(去掉可能的 v 前缀和空白字符) + VERSION=$(echo "$VERSION" | sed 's/^v//' | tr -d ' \n\r') VERSION_WITH_DASH=$(echo "$VERSION" | sed 's/\./-/g') + # 验证版本号格式 + if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-].*)?$ ]]; then + echo "⚠️ 警告: 版本号格式可能不标准: $VERSION" + fi + echo "version=$VERSION" >> $GITHUB_OUTPUT echo "version_with_dash=$VERSION_WITH_DASH" >> $GITHUB_OUTPUT diff --git a/release-web/examples/custom-version-source.yml b/release-web/examples/custom-version-source.yml new file mode 100644 index 0000000..d1d84c7 --- /dev/null +++ b/release-web/examples/custom-version-source.yml @@ -0,0 +1,73 @@ +name: 自定义版本源示例 + +on: + push: + branches: [main] + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 # 需要完整历史记录以获取 git tags + + - name: 设置环境 + uses: actions/xgj/setup-env@main + with: + docker-registry: "docker-registry.bjxgj.com" + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: 安装依赖 + uses: actions/xgj/npm-install@main + + # 情况1: 使用自定义版本文件路径 + - name: 发布(自定义版本文件) + uses: actions/xgj/release-web@main + with: + release-command: "echo '1.2.3' > ./custom-version.txt" + version-file: "./custom-version.txt" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + # 情况2: 依赖 git tag(无版本文件) + - name: 创建 git tag + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git tag v1.2.4 + + - name: 发布(基于 git tag) + uses: actions/xgj/release-web@main + with: + release-command: "echo 'Release without version file'" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + # 情况3: 依赖 package.json(推荐用于 Node.js 项目) + - name: 更新 package.json 版本 + run: npm version 1.2.5 --no-git-tag-version + + - name: 发布(基于 package.json) + uses: actions/xgj/release-web@main + with: + release-command: "npm run build" # 不生成版本文件 + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + # 情况4: 基于提交信息 + - name: 提交版本信息 + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git commit --allow-empty -m "release: 1.2.6" + + - name: 发布(基于提交信息) + uses: actions/xgj/release-web@main + with: + release-command: "echo 'Release from commit message'" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} diff --git a/release-web/examples/version-handling.yml b/release-web/examples/version-handling.yml new file mode 100644 index 0000000..ca59d34 --- /dev/null +++ b/release-web/examples/version-handling.yml @@ -0,0 +1,148 @@ +name: 版本处理示例 + +on: + push: + branches: [main] + +jobs: + test-version-handling: + runs-on: ubuntu-latest + + steps: + - name: 检出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 设置环境 + uses: actions/xgj/setup-env@main + with: + docker-registry: "docker-registry.bjxgj.com" + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + + - name: 安装依赖 + uses: actions/xgj/npm-install@main + + # 测试1: 版本文件包含 v 前缀 + - name: 创建带 v 前缀的版本文件 + run: echo "v1.2.3" > /tmp/version-with-v + + - name: 发布(版本文件带 v 前缀) + id: test1 + uses: actions/xgj/release-web@main + with: + release-command: "echo 'Test release with v prefix in file'" + version-file: "/tmp/version-with-v" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + - name: 验证版本输出(不应包含 v) + run: | + echo "版本输出: ${{ steps.test1.outputs.version }}" + if [[ "${{ steps.test1.outputs.version }}" == "1.2.3" ]]; then + echo "✅ 正确:版本文件 v 前缀已去除" + else + echo "❌ 错误:版本应该是 1.2.3,实际是 ${{ steps.test1.outputs.version }}" + exit 1 + fi + + # 测试2: Git tag 包含 v 前缀 + - name: 创建带 v 前缀的 git tag + run: | + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git tag v1.2.4 + # 删除版本文件,强制使用 git tag + rm -f /tmp/last-version /tmp/version-with-v + + - name: 发布(基于 git tag) + id: test2 + uses: actions/xgj/release-web@main + with: + release-command: "echo 'Test release with git tag'" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + - name: 验证 git tag 版本输出 + run: | + echo "Git tag 版本输出: ${{ steps.test2.outputs.version }}" + if [[ "${{ steps.test2.outputs.version }}" == "1.2.4" ]]; then + echo "✅ 正确:Git tag v 前缀已去除" + else + echo "❌ 错误:版本应该是 1.2.4,实际是 ${{ steps.test2.outputs.version }}" + exit 1 + fi + + # 测试3: package.json 包含 v 前缀(不常见但要处理) + - name: 修改 package.json 添加 v 前缀 + run: | + # 创建一个测试用的 package.json + echo '{"version": "v1.2.5"}' > package.json + rm -f /tmp/last-version + git tag -d v1.2.4 # 删除之前的 tag + + - name: 发布(基于 package.json) + id: test3 + uses: actions/xgj/release-web@main + with: + release-command: "echo 'Test release with package.json'" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + - name: 验证 package.json 版本输出 + run: | + echo "Package.json 版本输出: ${{ steps.test3.outputs.version }}" + if [[ "${{ steps.test3.outputs.version }}" == "1.2.5" ]]; then + echo "✅ 正确:Package.json v 前缀已去除" + else + echo "❌ 错误:版本应该是 1.2.5,实际是 ${{ steps.test3.outputs.version }}" + exit 1 + fi + + # 测试4: 提交信息包含 v 前缀 + - name: 创建带 v 前缀的提交信息 + run: | + echo '{"version": "0.0.1"}' > package.json # 重置 package.json + git config user.name "github-actions" + git config user.email "github-actions@github.com" + git add package.json + git commit --allow-empty -m "release: v1.2.6" + + - name: 发布(基于提交信息) + id: test4 + uses: actions/xgj/release-web@main + with: + release-command: "echo 'Test release with commit message'" + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + + - name: 验证提交信息版本输出 + run: | + echo "提交信息版本输出: ${{ steps.test4.outputs.version }}" + if [[ "${{ steps.test4.outputs.version }}" == "1.2.6" ]]; then + echo "✅ 正确:提交信息 v 前缀已去除" + else + echo "❌ 错误:版本应该是 1.2.6,实际是 ${{ steps.test4.outputs.version }}" + exit 1 + fi + + # 测试5: 版本号带横线格式 + - name: 验证版本带横线格式 + run: | + echo "版本带横线: ${{ steps.test4.outputs.version-with-dash }}" + if [[ "${{ steps.test4.outputs.version-with-dash }}" == "1-2-6" ]]; then + echo "✅ 正确:版本横线格式正确" + else + echo "❌ 错误:版本横线格式应该是 1-2-6,实际是 ${{ steps.test4.outputs.version-with-dash }}" + exit 1 + fi + + - name: 测试总结 + run: | + echo "🎉 所有版本处理测试通过!" + echo "✅ 版本文件 v 前缀处理正确" + echo "✅ Git tag v 前缀处理正确" + echo "✅ Package.json v 前缀处理正确" + echo "✅ 提交信息 v 前缀处理正确" + echo "✅ 版本横线格式正确" diff --git a/test-version-logic.sh b/test-version-logic.sh new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/test-version-logic.sh @@ -0,0 +1 @@ + \ No newline at end of file