forked from Gitlink/gitlink-cli
11 KiB
11 KiB
Workflow: Release Notes 生成
前置条件: 先阅读
../../gitlink-shared/SKILL.md了解认证、全局参数和安全规则。 AI Agent 工作流:此工作流专为 AI Agent 设计,用于自动生成版本发布说明。
AI Agent 从提交历史、Issue 和 PR 数据自动生成结构化的 Release Notes,确保发布文档的完整性和准确性。
工作流概述
Release Notes 生成工作流自动收集版本间的所有变更信息,整理成结构化的发布说明,包含新功能、Bug 修复、破坏性变更等重要信息。
适用场景
- 版本发布:为每个新版本生成发布说明
- 变更追踪:追踪版本间的具体变更
- 用户沟通:向用户清晰传达版本更新内容
- 历史记录:维护项目变更历史
工作流步骤
步骤 1:确定版本范围
# 获取最新标签
LATEST_TAG=$(gitlink-cli release +list --format json | \
jq -r '.data.releases[0].tag_name')
# 确定新版本号
NEW_TAG="v1.2.0"
# 或者获取两个标签之间的差异
BASE_TAG="v1.1.0"
HEAD_TAG="v1.2.0"
步骤 2:获取提交历史
# 获取版本间的提交比较
gitlink-cli api GET /:owner/:repo/compare/$BASE_TAG...$HEAD_TAG --format json
# 提取提交信息
COMMITS=$(gitlink-cli api GET /:owner/:repo/compare/$BASE_TAG...$HEAD_TAG --format json | \
jq '.data.commits[] |
{message: .commit.message,
author: .commit.author.name,
date: .commit.author.date,
sha: .sha}')
步骤 3:获取已关闭的 Issue
# 获取已关闭的 Issue
CLOSED_ISSUES=$(gitlink-cli issue +list --state closed --format json | \
jq '.data.issues[] |
select(.closed_at >= "'$START_DATE'") |
{id: .id,
subject: .subject,
labels: [.issue_tags[].name],
closed_at: .closed_at}')
步骤 4:获取合并的 PR
# 获取已合并的 PR
MERGED_PRS=$(gitlink-cli pr +list --state merged --format json | \
jq '.data.prs[] |
select(.merged_at >= "'$START_DATE'") |
{id: .id,
title: .title,
number: .number,
author: .author.login,
merged_at: .merged_at}')
步骤 5:分类和整理变更
# 按变更类型分类
FEATURES=()
BUG_FIXES=()
ENHANCEMENTS=()
BREAKING_CHANGES=()
# 分析 Issue 标签分类
while read -r issue; do
SUBJECT=$(echo "$issue" | jq -r '.subject')
LABELS=$(echo "$issue" | jq -r '.labels[]')
if echo "$LABELS" | grep -q "feature"; then
FEATURES+=("$SUBJECT")
elif echo "$LABELS" | grep -q "bug"; then
BUG_FIXES+=("$SUBJECT")
elif echo "$LABELS" | grep -q "enhancement"; then
ENHANCEMENTS+=("$SUBJECT")
fi
done <<< "$CLOSED_ISSUES"
# 分析提交信息
while read -r commit; do
MESSAGE=$(echo "$commit" | jq -r '.message')
if echo "$MESSAGE" | grep -iq "BREAKING"; then
BREAKING_CHANGES+=("$MESSAGE")
fi
done <<< "$COMMITS"
步骤 6:生成 Release Notes
# 生成结构化的 Release Notes
RELEASE_NOTES="# 🚀 Release Notes for $NEW_TAG
## 📝 What's Changed
### ✨ New Features
$(for feature in "${FEATURES[@]}"; do
echo "- $feature"
done)
### 🐛 Bug Fixes
$(for fix in "${BUG_FIXES[@]}"; do
echo "- $fix"
done)
### 🔧 Enhancements
$(for enhancement in "${ENHANCEMENTS[@]}"; do
echo "- $enhancement"
done)
### ⚠️ Breaking Changes
$(for breaking in "${BREAKING_CHANGES[@]}"; do
echo "- $breaking"
done)"
# 创建 Release
gitlink-cli release +create --tag $NEW_TAG --name "$NEW_TAG" --body "$RELEASE_NOTES"
AI Agent 集成示例
Claude Code 等 AI Agent 可以深度集成此工作流:
# AI Agent 生成 Release Notes
def generate_release_notes(owner, repo, new_version):
"""AI Agent 自动生成发布说明"""
# 1. 获取版本信息
prev_version = get_latest_release(owner, repo)
commits = compare_revisions(owner, repo, prev_version, new_version)
issues = get_closed_issues(owner, repo, since=prev_version)
prs = get_merged_prs(owner, repo, since=prev_version)
# 2. AI 分析变更
changes = analyze_changes(commits, issues, prs)
# 3. 生成发布说明
release_notes = format_release_notes(new_version, changes, prev_version)
# 4. 创建 Release
create_release(owner, repo, new_version, release_notes)
return release_notes
def analyze_changes(commits, issues, prs):
"""AI 智能分析变更内容"""
changes = {
'features': [],
'bug_fixes': [],
'enhancements': [],
'breaking_changes': [],
'contributors': set(),
'performance_improvements': [],
'security_fixes': []
}
# 分析 Issue
for issue in issues:
labels = [label['name'] for label in issue.get('issue_tags', [])]
subject = issue['subject']
if 'feature' in labels:
changes['features'].append(format_issue_reference(issue))
elif 'bug' in labels:
changes['bug_fixes'].append(format_issue_reference(issue))
elif 'enhancement' in labels:
changes['enhancements'].append(format_issue_reference(issue))
elif 'security' in labels:
changes['security_fixes'].append(format_issue_reference(issue))
# 分析提交信息
for commit in commits:
message = commit['commit']['message']
# 使用 AI 分析提交消息
analysis = analyze_commit_message(message)
if analysis.get('breaking_change'):
changes['breaking_changes'].append(message)
elif analysis.get('performance'):
changes['performance_improvements'].append(message)
# 收集贡献者
changes['contributors'].add(commit['author']['name'])
return changes
def format_release_notes(version, changes, prev_version):
"""AI 生成结构化发布说明"""
notes = f"""# 🎉 Release {version}
## 📊 变更统计
- **新功能**: {len(changes['features'])} 个
- **Bug 修复**: {len(changes['bug_fixes'])} 个
- **功能改进**: {len(changes['enhancements'])} 个
- **破坏性变更**: {len(changes['breaking_changes'])} 个
"""
if changes['features']:
notes += "\n## ✨ 新功能\n"
notes += "\n".join(f"- {feature}" for feature in changes['features'])
notes += "\n"
if changes['bug_fixes']:
notes += "\n## 🐛 Bug 修复\n"
notes += "\n".join(f"- {fix}" for fix in changes['bug_fixes'])
notes += "\n"
if changes['breaking_changes']:
notes += "\n## ⚠️ 破坏性变更\n"
notes += "\n".join(f"- {change}" for change in changes['breaking_changes'])
notes += "\n"
if changes['contributors']:
notes += f"\n## 🙏 贡献者\n"
notes += ", ".join(sorted(changes['contributors']))
notes += "\n"
notes += f"\n---\n**完整变更日志**: https://www.gitlink.org.cn/{owner}/{repo}/compare/{prev_version}...{version}"
return notes
def analyze_commit_message(message):
"""AI 分析提交消息"""
return {
'breaking_change': bool(re.search(r'BREAKING|breaking|!', message)),
'performance': bool(re.search(r'performance|优化|提升', message, re.I)),
'security': bool(re.search(r'security|安全|漏洞', message, re.I))
}
Release Notes 模板
标准模板
# 🎉 Release {VERSION}
## 📊 变更统计
- **新功能**: {FEATURE_COUNT} 个
- **Bug 修复**: {BUG_FIX_COUNT} 个
- **功能改进**: {ENHANCEMENT_COUNT} 个
- **破坏性变更**: {BREAKING_COUNT} 个
## ✨ 新功能
{FEATURES_LIST}
## 🐛 Bug 修复
{BUG_FIXES_LIST}
## 🔧 功能改进
{ENHANCEMENTS_LIST}
## ⚠️ 破坏性变更
{BREAKING_CHANGES_LIST}
## 🙏 贡献者
{CONTRIBUTORS_LIST}
## 📥 安装
```bash
# 使用 npm
npm install {PACKAGE}@{VERSION}
# 使用 yarn
yarn add {PACKAGE}@{VERSION}
# 使用 pnpm
pnpm add {PACKAGE}@{VERSION}
🔄 升级指南
{UPGRADE_GUIDE}
📚 文档
完整文档请查看: https://www.gitlink.org.cn/{OWNER}/{REPO}/wiki
完整变更日志: https://www.gitlink.org.cn/{OWNER}/{REPO}/compare/{PREV_VERSION}...{VERSION}
### 简化模板
```markdown
# {VERSION}
## 新增
{FEATURES}
## 修复
{BUG_FIXES}
## 改进
{ENHANCEMENTS}
## 贡献者
{CONTRIBUTORS}
## 链接
- [完整变更](https://www.gitlink.org.cn/{OWNER}/{REPO}/compare/{PREV_VERSION}...{VERSION})
- [问题追踪](https://www.gitlink.org.cn/{OWNER}/{REPO}/issues)
自动化分类规则
基于提交信息和 Issue 标签的自动分类:
RELEASE_CATEGORIES = {
'features': {
'labels': ['feature', 'enhancement'],
'commit_keywords': ['feat:', 'add', 'new'],
'icon': '✨',
'title': '新功能'
},
'bug_fixes': {
'labels': ['bug', 'fix'],
'commit_keywords': ['fix:', 'bugfix'],
'icon': '🐛',
'title': 'Bug 修复'
},
'enhancements': {
'labels': ['improvement', 'optimize'],
'commit_keywords': ['improve:', 'optimize:', 'refactor:'],
'icon': '🔧',
'title': '功能改进'
},
'breaking_changes': {
'labels': ['breaking', 'major'],
'commit_keywords': ['BREAKING', 'breaking:', '!'],
'icon': '⚠️',
'title': '破坏性变更'
},
'security': {
'labels': ['security', 'vulnerability'],
'commit_keywords': ['security:', 'fix security'],
'icon': '🔒',
'title': '安全修复'
}
}
版本号规范
遵循语义化版本 (Semantic Versioning):
MAJOR.MINOR.PATCH
MAJOR: 不兼容的 API 变更
MINOR: 向后兼容的功能新增
PATCH: 向后兼容的 Bug 修复
版本号示例:
1.0.0→1.1.0:新增功能1.1.0→1.1.1:Bug 修复1.1.1→2.0.0:破坏性变更
质量检查
发布前检查清单:
- Release Notes 完整性检查
- 变更统计准确性验证
- 破坏性变更标识
- 升级指南完整性
- 文档链接正确性
- 安装指令有效性
- 贡献者列表完整性
最佳实践
- 定期发布:建立定期发布节奏
- 变更追踪:确保所有变更都被记录
- 清晰分类:使用明确的分类和标签
- 用户友好:提供升级指南和迁移说明
- 版本规范:遵循语义化版本规范
References
- workflow-issue-triage — Issue 分类工作流
- workflow-pr-review — PR 审查工作流
- gitlink-workflow — 工作流总览
- gitlink-shared — 认证和全局参数
- release +create — 创建 Release
- release +list — 列出 Release