actions-template/WORKFLOW.md

22 KiB
Raw Blame History

📦 Tag Release Automation

自动生成 CHANGELOG 并创建 Release 的一体化工作流,支持语义版本号SemVer和内容叠加


📂 文件位置

.gitea/workflows/
└── changelog-and-release.yaml    # CHANGELOG 生成 + Release 创建

🚀 快速开始

1 配置 Gitea Token

生成 Token

  1. 登录 Gitea → 右上角头像 → 设置 (Settings)应用 (Applications)
  2. 点击 生成新令牌 (Generate New Token)
  3. 配置权限:
    • repo - 完整的仓库访问权限(必需)
  4. 复制生成的 Token⚠️ 只显示一次)

添加 Secret

推荐方式:仓库级别配置

  1. 进入仓库 → 设置 (Settings)ActionsSecrets
  2. 点击 新建 Secret (New Secret)
  3. 填写:
    • 名称GITEA_TOKEN
    • :粘贴刚才的 token
  4. 点击 保存

💡 提示:如果有多个仓库需要使用,可以在个人设置中添加全局 Secret

2 部署 Workflow

# 创建目录
mkdir -p .gitea/workflows

# 复制文件(将文件重命名为 changelog-and-release.yaml
cp changelog-and-release.yaml .gitea/workflows/

# 提交
git add .gitea/workflows/
git commit -m "ci: add changelog and release automation"
git push origin main

3 自定义配置

打开 changelog-and-release.yaml,找到 ⚙️ Configuration 步骤(约第 10-60 行),所有配置都在这里:

- name: ⚙️ Configuration
  id: config
  run: |
    # ========================================
    # 📝 自定义配置区域 - 在此修改所有配置
    # ========================================

    # 📌 语义版本号规范 (SemVer)
    # 格式: MAJOR.MINOR.PATCH[-prerelease]
    # 
    # 示例: 1.0.0, 1.1.0, 1.1.1, 1.0.0-beta1, 2.0.0-rc1
    # 
    # ⚠️ 重要规则:
    #   1. 开发版本以 .0 开始 (如 1.0.0-beta1, 不是 1.0.1-beta1)
    #   2. 多个开发版本会累加到同一 CHANGELOG 区域 (推荐使用 strip 模式)
    #   3. CHANGELOG 内容是叠加而非覆盖
    # 
    # 📖 详细规范请参考: CONVENTIONS.md

    # Gitea 服务器地址(用于生成头像链接)
    GITEA_SERVER="https://git.mytsl.cn"

    # CHANGELOG 配置
    CHANGELOG_SECTION_TITLE="### :pencil: What's Changed"
    CHANGELOG_CONTRIBUTORS_TITLE="### :busts_in_silhouette: Contributors"

    # CHANGELOG 版本号处理方式
    # - "full": 使用完整 tag 名称1.0.0-beta → ## :bookmark: 1.0.0-beta
    # - "strip": 去除 pre-release 后缀1.0.0-beta1 → ## :bookmark: 1.0.0
    #            ⚠️ 推荐使用 "strip" 模式以支持多个开发版本叠加到同一CHANGELOG区域
    CHANGELOG_VERSION_MODE="strip"

    # Release 配置
    RELEASE_TITLE="{version}"  # 可用变量: {version}

    # Pre-release 配置
    # - "false": 正式版本(会被标记为 latest
    # - "true": 预发布版本(会被标记为 pre-release
    # - "auto": 自动判断(根据 tag 名称中是否包含 alpha/beta/rc
    RELEASE_PRERELEASE_MODE="auto"

    # Draft 配置(是否创建为草稿)
    RELEASE_IS_DRAFT="false"  # true 或 false

    # 需要忽略的提交模式
    IGNORE_PATTERNS=(
      "^Merge "
      "^:memo: Auto update CHANGELOG"
      "\[skip ci\]"
      "\[ci skip\]"
      "^style: "
      "^chore: format"
    )

    # Git 提交消息格式
    COMMIT_MESSAGE=":memo: Auto update CHANGELOG for {version} [skip ci]"

    # 额外要上传到 Release 的文件
    ADDITIONAL_RELEASE_FILES=""  # 例如: "README.md LICENSE"    

常见配置示例

修改 Gitea 服务器地址

GITEA_SERVER="https://your-gitea.com"

修改 CHANGELOG 标题为中文

CHANGELOG_SECTION_TITLE="### :pencil: 变更内容"
CHANGELOG_CONTRIBUTORS_TITLE="### :busts_in_silhouette: 贡献者"

配置 CHANGELOG 版本号处理方式

# ⭐ 推荐strip 模式(支持内容叠加)
CHANGELOG_VERSION_MODE="strip"
# 所有相同前缀的版本共享同一个 CHANGELOG 区域,内容累积
# 1.0.0-beta1 → ## :bookmark: 1.0.0
# 1.0.0-beta2 → ## :bookmark: 1.0.0 (追加内容)
# 1.0.0       → ## :bookmark: 1.0.0 (追加内容)

# 方式 2: full 模式(每个 tag 独立条目)
CHANGELOG_VERSION_MODE="full"
# 每个 tag 都有独立的 CHANGELOG 条目
# 1.0.0-beta1 → ## :bookmark: 1.0.0-beta1
# 1.0.0-beta2 → ## :bookmark: 1.0.0-beta2
# 1.0.0       → ## :bookmark: 1.0.0

推荐使用 strip 模式的原因

  1. 支持内容叠加 - 多个开发版本的提交累积在一起
  2. 避免重复 - 所有版本的改动集中在一个区域
  3. 完整历史 - 正式发布时 CHANGELOG 已包含所有开发阶段的提交
  4. 符合最佳实践 - 大多数开源项目的做法

strip 模式工作流程示例

# 1. 推送第一个 beta 版本
git push origin 1.0.0-beta1
# → CHANGELOG: ## :bookmark: 1.0.0(创建新区域,添加 beta1 的提交)
# → Release: 1.0.0-beta1 (Pre-release 🏷️)

# 2. 推送第二个 beta 版本
git push origin 1.0.0-beta2
# → CHANGELOG: ## :bookmark: 1.0.0(叠加 beta2 的提交到现有区域)
# → Release: 1.0.0-beta2 (Pre-release 🏷️)

# 3. 推送 rc 版本
git push origin 1.0.0-rc1
# → CHANGELOG: ## :bookmark: 1.0.0(继续叠加 rc1 的提交)
# → Release: 1.0.0-rc1 (Pre-release 🏷️)

# 4. 推送正式版本
git push origin 1.0.0
# → CHANGELOG: ## :bookmark: 1.0.0(叠加正式版的提交,现在包含完整历史)
# → Release: 1.0.0 (Latest ✅)

生成的 CHANGELOG 示例(叠加模式):

## :bookmark: 1.0.0

### :pencil: What's Changed

- :sparkles: Add user authentication (来自 beta1)
- :sparkles: Add profile page (来自 beta1)
- :bug: Fix login redirect (来自 beta2)
- :sparkles: Add password reset (来自 beta2)
- :memo: Update documentation (来自 rc1)
- :bug: Fix validation error (来自正式版)

### :busts_in_silhouette: Contributors

[所有版本的贡献者,自动去重]

---

修改 Release 标题

RELEASE_TITLE="{version}"              # → 1.0.0
RELEASE_TITLE="v{version}"             # → v1.0.0
RELEASE_TITLE="Release {version}"      # → Release 1.0.0
RELEASE_TITLE="🎉 {version}"           # → 🎉 1.0.0

配置 Pre-release 标记

# 方式 1: 自动判断(推荐)
RELEASE_PRERELEASE_MODE="auto"
# tag 包含 alpha/beta/rc/pre/preview/dev/test → Pre-release 🏷️
# 其他 tag → Latest (Stable) ✅

# 方式 2: 始终标记为正式版本
RELEASE_PRERELEASE_MODE="false"
# 所有 Release 都标记为 Latest ✅

# 方式 3: 始终标记为预发布版本
RELEASE_PRERELEASE_MODE="true"
# 所有 Release 都标记为 Pre-release 🏷️

示例效果

# auto 模式下:
1.0.0             → Latest ✅
1.0.0-beta1       → Pre-release 🏷️
1.0.0-rc1         → Pre-release 🏷️
1.0.0-alpha1      → Pre-release 🏷️
1.0.0.dev         → Pre-release 🏷️

创建为草稿

RELEASE_IS_DRAFT="true"  # Release 创建后不会立即发布,需要手动发布

添加更多忽略的提交类型

IGNORE_PATTERNS=(
  "^Merge "
  "^:memo: Auto update CHANGELOG"
  "\[skip ci\]"
  "^test: "        # 添加:忽略测试
  "^docs: "        # 添加:忽略文档
  "^refactor: "    # 添加:忽略重构
)

上传额外的文件到 Release

ADDITIONAL_RELEASE_FILES="README.md LICENSE docs/guide.pdf"

自定义提交消息

COMMIT_MESSAGE="docs: update CHANGELOG for {version}"
COMMIT_MESSAGE="chore(release): update CHANGELOG [{version}]"

4 创建 Release

完整开发流程示例

# === 第一阶段Alpha 内部测试 ===
git commit -m ":sparkles: Add user authentication"
git tag 1.0.0-alpha1
git push origin 1.0.0-alpha1

git commit -m ":sparkles: Add user profile"
git tag 1.0.0-alpha2
git push origin 1.0.0-alpha2

# === 第二阶段Beta 公开测试 ===
git commit -m ":bug: Fix login redirect"
git tag 1.0.0-beta1
git push origin 1.0.0-beta1

git commit -m ":sparkles: Add password reset"
git tag 1.0.0-beta2
git push origin 1.0.0-beta2

# === 第三阶段RC 发布候选 ===
git commit -m ":memo: Update documentation"
git tag 1.0.0-rc1
git push origin 1.0.0-rc1

# === 第四阶段:正式发布 ===
git tag 1.0.0
git push origin 1.0.0

# === 后续版本 ===
# 新增功能(向后兼容)
git commit -m ":sparkles: Add email notifications"
git tag 1.1.0
git push origin 1.1.0

# Bug 修复
git commit -m ":bug: Fix email sending"
git tag 1.1.1
git push origin 1.1.1

# 破坏性变更
git commit -m ":boom: Change API format"
git tag 2.0.0
git push origin 2.0.0

🎉 完成!工作流会自动:

  1. 加载自定义配置
  2. 生成/叠加 CHANGELOG 条目
  3. 合并并去重贡献者
  4. 提交并推送到 main 分支
  5. 创建 Release自动识别 Pre-release
  6. 上传 CHANGELOG.md 及额外文件

📋 工作原理

触发条件

推送数字开头的 tag

# ✅ 会触发
git push origin 1.0.0
git push origin 1.1.0-beta1
git push origin 2.0.0-rc1

# ❌ 不会触发(不是数字开头)
git push origin v1.0.0
git push origin release-1.0

执行流程

Tag Push (1.0.0-beta1)
    ↓
⚙️ 加载配置参数
    ↓
📂 检出代码
    ↓
🤖 检查是否为 bot 提交
    ↓
📋 检查版本是否已存在1.0.0
    ↓ 已存在 → 叠加模式
    ↓ 不存在 → 创建新条目
📝 生成 CHANGELOG 条目
    ├─ 提取旧的提交记录(如果存在)
    ├─ 提取旧的贡献者(如果存在)
    ├─ 追加新的提交记录
    ├─ 合并并去重贡献者
    └─ 生成完整的条目
    ↓
📤 提交并推送
    ↓
🗑️ 删除旧 Release
    ↓
🚀 创建新 Release
    ├─ 使用配置的标题格式
    ├─ 自动识别 Pre-release
    └─ 上传配置的附件列表
    ↓
✅ 完成

版本号处理逻辑

Strip 模式(推荐)

Tag: 1.0.0-beta1
  ↓ strip 处理
CHANGELOG Version: 1.0.0
  ↓
检查 1.0.0 是否存在?
  ├─ 不存在 → 创建新区域
  └─ 已存在 → 叠加内容

Tag: 1.0.0-beta2
  ↓ strip 处理
CHANGELOG Version: 1.0.0
  ↓
检查 1.0.0 是否存在?
  └─ 已存在 → 叠加内容(保留 beta1 的提交)

Tag: 1.0.0
  ↓ strip 处理
CHANGELOG Version: 1.0.0
  ↓
检查 1.0.0 是否存在?
  └─ 已存在 → 叠加内容(保留所有之前的提交)

配置加载日志示例

执行时会显示配置摘要:

======================================
⚙️  Loading workflow configuration
======================================

📋 Configuration Summary:
  🏷️  Tag version: 1.0.0-beta1
  📝 CHANGELOG version: 1.0.0
  🌐 Gitea Server: https://git.mytsl.cn
  📄 CHANGELOG Title: ### :pencil: What's Changed
  🚀 Release Title: 1.0.0-beta1
  🏷️  Pre-release: yes (auto-detected: 1.0.0-beta1 contains pre-release keyword)
  📄 Draft: false
  💬 Commit Message: :memo: Auto update CHANGELOG for 1.0.0-beta1 [skip ci]
  📎 Additional Files: README.md LICENSE

✅ Configuration loaded successfully

生成的内容示例

CHANGELOG.md叠加模式

## :bookmark: 1.0.0

### :pencil: What's Changed

- :sparkles: Add user authentication ([a1b2c3d](链接)) by @developer1
- :sparkles: Add user profile ([e4f5g6h](链接)) by @developer1
- :bug: Fix login redirect ([i7j8k9l](链接)) by @developer2
- :sparkles: Add password reset ([m0n1o2p](链接)) by @developer2

### :busts_in_silhouette: Contributors

<a href="https://git.mytsl.cn/developer1">
  <img src="https://git.mytsl.cn/developer1.png" alt="developer1" width="35" height="35" />
</a>
<a href="https://git.mytsl.cn/developer2">
  <img src="https://git.mytsl.cn/developer2.png" alt="developer2" width="35" height="35" />
</a>

---

Release

  • 标题:根据 RELEASE_TITLE 生成(例如:1.0.0-beta1v1.0.0-beta1
  • 标记
    • RELEASE_PRERELEASE_MODE="auto" → 根据 tag 名称自动判断
    • RELEASE_PRERELEASE_MODE="false" → Latest
    • RELEASE_PRERELEASE_MODE="true" → Pre-release 🏷️
  • 内容CHANGELOG 中该版本的完整内容(包含所有叠加的提交)
  • 附件CHANGELOG.md + ADDITIONAL_RELEASE_FILES 中的文件

Latest Release 示例

✅ Latest

1.0.0                           ← RELEASE_TITLE

### :pencil: What's Changed
- :sparkles: Add user authentication ([a1b2c3d](链接))
- :sparkles: Add user profile ([e4f5g6h](链接))
- :bug: Fix login redirect ([i7j8k9l](链接))
- :sparkles: Add password reset ([m0n1o2p](链接))

### :busts_in_silhouette: Contributors
[所有贡献者头像]

Pre-release 示例

🏷️ Pre-release

1.0.0-beta1                     ← RELEASE_TITLE

### :pencil: What's Changed
- :sparkles: Add user authentication ([a1b2c3d](链接))
- :sparkles: Add user profile ([e4f5g6h](链接))

🎨 配置示例库

示例 1标准 SemVer 配置(推荐)

GITEA_SERVER="https://git.example.com"
CHANGELOG_SECTION_TITLE="### :pencil: What's Changed"
CHANGELOG_CONTRIBUTORS_TITLE="### :busts_in_silhouette: Contributors"
CHANGELOG_VERSION_MODE="strip"         # 支持内容叠加
RELEASE_TITLE="{version}"
RELEASE_PRERELEASE_MODE="auto"         # 自动识别 beta/rc 等
COMMIT_MESSAGE=":memo: Auto update CHANGELOG for {version} [skip ci]"

示例 2中文环境

GITEA_SERVER="https://git.example.com"
CHANGELOG_SECTION_TITLE="### :pencil: 变更内容"
CHANGELOG_CONTRIBUTORS_TITLE="### :busts_in_silhouette: 贡献者"
CHANGELOG_VERSION_MODE="strip"
RELEASE_TITLE="版本 {version}"
RELEASE_PRERELEASE_MODE="auto"
COMMIT_MESSAGE="文档: 更新 CHANGELOG [{version}] [skip ci]"

示例 3详细记录

GITEA_SERVER="https://git.example.com"
CHANGELOG_SECTION_TITLE="### :clipboard: What's Changed in This Version"
CHANGELOG_CONTRIBUTORS_TITLE="### :heart: Special Thanks To"
CHANGELOG_VERSION_MODE="strip"
RELEASE_TITLE="Release {version}"
RELEASE_PRERELEASE_MODE="auto"
RELEASE_IS_DRAFT="false"
COMMIT_MESSAGE=":memo: Automated CHANGELOG update for version {version} [skip ci]"
ADDITIONAL_RELEASE_FILES="README.md LICENSE CHANGELOG.md docs/MIGRATION.md"
IGNORE_PATTERNS=(
  "^Merge "
  "^:memo: Auto update CHANGELOG"
  "\[skip ci\]"
  "^Bump version"
  "^style: "
  "^chore: format"
  "^chore: lint"
  "^test: "
  "^docs: update readme"
)

示例 4开发分支始终 Pre-release

GITEA_SERVER="https://git.example.com"
CHANGELOG_SECTION_TITLE="### :test_tube: Development Changes"
CHANGELOG_CONTRIBUTORS_TITLE="### :busts_in_silhouette: Contributors"
CHANGELOG_VERSION_MODE="strip"
RELEASE_TITLE="Dev Build {version}"
RELEASE_PRERELEASE_MODE="true"         # 始终标记为 pre-release
COMMIT_MESSAGE=":test_tube: Update CHANGELOG for dev build {version} [skip ci]"

示例 5草稿模式

GITEA_SERVER="https://git.example.com"
CHANGELOG_SECTION_TITLE="### :pencil: What's Changed"
CHANGELOG_CONTRIBUTORS_TITLE="### :busts_in_silhouette: Contributors"
CHANGELOG_VERSION_MODE="strip"
RELEASE_TITLE="{version}"
RELEASE_PRERELEASE_MODE="auto"
RELEASE_IS_DRAFT="true"                # 创建为草稿
COMMIT_MESSAGE=":memo: Auto update CHANGELOG for {version} [skip ci]"

📖 版本号最佳实践

快速参考

版本演进示例

0.1.0 → 0.2.0 → 1.0.0 (首个稳定版) → 1.1.0 (新功能) → 1.1.1 (Bug修复) → 2.0.0 (破坏性变更)

何时递增版本号

  • MAJOR:不兼容的 API 修改、破坏性变更
  • MINOR:新增功能但保持向后兼容
  • PATCHBug 修复、安全补丁

Pre-release 版本命名

1.0.0-alpha1   # 内部测试,可能不稳定
1.0.0-beta1    # 公开测试,功能基本完成
1.0.0-rc1      # 发布候选,准备正式发布

版本号检查清单

  • 格式:MAJOR.MINOR.PATCH (不要 v 前缀)
  • 开发版本以 .0 开始 (如 1.0.0-beta1)
  • Pre-release 后缀完整 (beta1 不是 b1)
  • CHANGELOG_VERSION_MODE 设置为 "strip"

📖 详细说明请参考CONVENTIONS.md - 包含完整的 SemVer 规范、更新规则和示例


常见问题

Q1: 为什么推荐使用 strip 模式?

原因

  1. 支持内容叠加 - 多个开发版本的提交会累积在同一个 CHANGELOG 区域
  2. 完整的开发历史 - 正式发布时CHANGELOG 已包含所有开发阶段的提交
  3. 避免重复 - 不需要为每个 beta/rc 版本创建独立的 CHANGELOG 条目
  4. 便于阅读 - 所有相关的变更集中在一起

对比

# Strip 模式
1.0.0-beta1, 1.0.0-beta2, 1.0.0 → 所有提交在 ## :bookmark: 1.0.0

# Full 模式
1.0.0-beta1 → ## :bookmark: 1.0.0-beta1
1.0.0-beta2 → ## :bookmark: 1.0.0-beta2
1.0.0       → ## :bookmark: 1.0.0

Q2: 如何修改配置?

所有配置都在第一个步骤中,只需编辑 changelog-and-release.yaml⚙️ Configuration 步骤即可。

修改后提交推送:

git add .gitea/workflows/changelog-and-release.yaml
git commit -m "ci: update workflow configuration"
git push

下次推送 tag 时会使用新配置。


Q3: 版本号格式错误会怎样?

常见错误

❌ v1.0.0           # 不应该有 v 前缀
❌ 1.0.1-beta1      # 开发版本应该从 .0 开始
❌ 1.0.0beta1       # 缺少连字符
❌ 1.0.0-b1         # 后缀应该完整写 beta1

影响

  • 工作流仍会执行
  • 但可能无法正确识别为 Pre-release
  • CHANGELOG 版本号可能不符合预期

Q4: 如何查看 CHANGELOG 是否正确叠加?

检查步骤

  1. 查看 CHANGELOG.md 文件
  2. 找到对应的版本区域(如 ## :bookmark: 1.0.0
  3. 确认包含所有 beta/rc 版本的提交

示例

## :bookmark: 1.0.0

### :pencil: What's Changed

- 提交 1来自 1.0.0-beta1
- 提交 2来自 1.0.0-beta1
- 提交 3来自 1.0.0-beta2
- 提交 4来自 1.0.0-rc1
- 提交 5来自 1.0.0

Q5: 贡献者重复怎么办?

不用担心! 工作流会自动去重贡献者。

如果同一个人在多个版本都有贡献,他们的头像只会出现一次。


Q6: Workflow 没有触发?

检查清单

  • Workflow 文件在 .gitea/workflows/ 目录下
  • 文件名为 changelog-and-release.yaml(或 .yml
  • Tag 格式正确(数字开头,如 1.0.01.0.0-beta1
  • Runner 已部署并正常运行
  • 仓库已启用 Actions
  • GITEA_TOKEN 已正确配置

Q7: 提示 "GITEA_TOKEN not found"

原因Token 未正确配置

解决方法

  1. 确认已添加名为 GITEA_TOKEN 的 Secret
  2. 确认 Token 具有 repo 权限
  3. 尝试重新生成并配置 Token

Q8: CHANGELOG 没有更新?

可能原因

  1. 没有新的有效提交
  2. 所有提交都匹配了 IGNORE_PATTERNS 中的规则
  3. 版本已存在且是 bot 提交

检查方法

# 查看两个 tag 之间的提交
git log $(git describe --tags --abbrev=0 @^)..@ --oneline --no-merges

# 检查 workflow 日志中的 "Found X valid commits"

Q9: 如何跳过自动化?

在 commit 消息中添加 [skip ci]

git commit -m "docs: update readme [skip ci]"

注意Tag 推送无法跳过,因为 workflow 在 tag 推送时触发


Q10: 什么时候使用 full 模式?

使用场景

  • 你希望每个 tag 都有独立的 CHANGELOG 条目
  • 不需要累积开发版本的提交
  • 每个版本的变更需要完全独立

大多数情况下,推荐使用 strip 模式。


Q11: Release 标记Latest/Pre-release是如何工作的

GitHub/Gitea 的自动标记规则

  1. Latest最新稳定版

    • 自动标记给最新的非 pre-release 版本
    • 显示绿色的 "Latest" 标签
  2. Pre-release预发布版

    • 通过 API 设置 prerelease: true
    • 显示橙色的 "Pre-release" 标签 🏷️
    • 不会被标记为 Latest

auto 模式识别的关键词

  • alpha, beta, rc, pre, preview, dev, test

示例

1.0.0             → Latest ✅
1.0.0-beta1       → Pre-release 🏷️
1.0.0-rc1         → Pre-release 🏷️
1.1.0             → Latest ✅ (1.0.0 变为旧版本)

🔍 调试技巧

查看配置加载情况

每次执行都会在日志开头显示配置摘要:

======================================
⚙️  Loading workflow configuration
======================================

📋 Configuration Summary:
  🏷️  Tag version: 1.0.0-beta1
  📝 CHANGELOG version: 1.0.0
  🌐 Gitea Server: https://git.mytsl.cn
  📝 CHANGELOG Title: ### :pencil: What's Changed
  🚀 Release Title: 1.0.0-beta1
  🏷️  Pre-release: yes (auto-detected)
  💬 Commit Message: :memo: Auto update CHANGELOG for 1.0.0-beta1 [skip ci]
  📎 Additional Files: none

本地测试配置

提取 Configuration 步骤中的 bash 代码,在本地运行测试:

#!/bin/bash

# 模拟环境变量
export github_ref_name="1.0.0-beta1"

# 复制你的配置
GITEA_SERVER="https://git.mytsl.cn"
CHANGELOG_VERSION_MODE="strip"
RELEASE_TITLE="{version}"
COMMIT_MESSAGE=":memo: Auto update CHANGELOG for {version} [skip ci]"

# 测试版本处理
VERSION="$github_ref_name"
if [[ "$CHANGELOG_VERSION_MODE" == "strip" ]]; then
  CHANGELOG_VERSION=$(echo "$VERSION" | sed -E 's/-(alpha|beta|rc|pre|preview|dev|test)[0-9]*$//')
  echo "Tag: $VERSION → CHANGELOG: $CHANGELOG_VERSION"
fi

# 测试变量替换
RELEASE_TITLE="${RELEASE_TITLE//\{version\}/$VERSION}"
COMMIT_MSG="${COMMIT_MESSAGE//\{version\}/$VERSION}"

echo "Release Title: $RELEASE_TITLE"
echo "Commit Message: $COMMIT_MSG"

验证版本号格式

# 测试版本号是否符合规范
version="1.0.0-beta1"

# 检查是否数字开头
if [[ "$version" =~ ^[0-9] ]]; then
  echo "✅ 格式正确"
else
  echo "❌ 版本号必须以数字开头"
fi

# 检查是否包含 pre-release 标识
if [[ "$version" =~ (alpha|beta|rc|pre|preview|dev|test) ]]; then
  echo "🏷️ 将被识别为 Pre-release"
else
  echo "✅ 将被识别为 Latest"
fi