# Workflow: Release Notes 生成

> **前置条件：** 先阅读 [`../../gitlink-shared/SKILL.md`](../../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。
> **AI Agent 工作流**：此工作流专为 AI Agent 设计，用于自动生成版本发布说明。

AI Agent 从提交历史、Issue 和 PR 数据自动生成结构化的 Release Notes，确保发布文档的完整性和准确性。

## 工作流概述

Release Notes 生成工作流自动收集版本间的所有变更信息，整理成结构化的发布说明，包含新功能、Bug 修复、破坏性变更等重要信息。

## 适用场景

- **版本发布**：为每个新版本生成发布说明
- **变更追踪**：追踪版本间的具体变更
- **用户沟通**：向用户清晰传达版本更新内容
- **历史记录**：维护项目变更历史

## 工作流步骤

### 步骤 1：确定版本范围

```bash
# 获取最新标签
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：获取提交历史

```bash
# 获取版本间的提交比较
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

```bash
# 获取已关闭的 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

```bash
# 获取已合并的 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：分类和整理变更

```bash
# 按变更类型分类
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

```bash
# 生成结构化的 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"
```

## 完整工作流示例

```bash
#!/bin/bash

# Release Notes 自动生成脚本

OWNER="myuser"
REPO="myproject"
NEW_VERSION=$1

if [ -z "$NEW_VERSION" ]; then
    echo "使用方法: $0 <version>"
    exit 1
fi

echo "为版本 $NEW_VERSION 生成 Release Notes..."

# 1. 获取上一个版本
PREV_VERSION=$(gitlink-cli release +list --owner $OWNER --repo $REPO --format json | \
  jq -r '.data.releases[0].tag_name')

echo "上一个版本: $PREV_VERSION"
echo "新版本: $NEW_VERSION"

# 2. 获取提交比较
COMPARE_DATA=$(gitlink-cli api GET "/$OWNER/$REPO/compare/$PREV_VERSION...$NEW_VERSION" --format json)
COMMITS=$(echo "$COMPARE_DATA" | jq -r '.data.commits')

# 3. 获取已关闭的 Issue
ISSUES=$(gitlink-cli issue +list --owner $OWNER --repo $REPO --state closed --format json | \
  jq '.data.issues[]')

# 4. 获取已合并的 PR
PRS=$(gitlink-cli pr +list --owner $OWNER --repo $REPO --state merged --format json | \
  jq '.data.prs[]')

# 5. 分析变更数据
FEATURE_COUNT=0
BUG_FIX_COUNT=0
ENHANCEMENT_COUNT=0
BREAKING_COUNT=0

# 分析 Issue
FEATURES=$(echo "$ISSUES" | jq -r 'select(.issue_tags[]?.name == "feature") | "- \(.subject) (#\(.id))"')
BUG_FIXES=$(echo "$ISSUES" | jq -r 'select(.issue_tags[]?.name == "bug") | "- \(.subject) (#\(.id))"')
ENHANCEMENTS=$(echo "$ISSUES" | jq -r 'select(.issue_tags[]?.name == "enhancement") | "- \(.subject) (#\(.id))"')

# 分析提交中的破坏性变更
BREAKING_CHANGES=$(echo "$COMMITS" | jq -r 'select(.commit.message | contains("BREAKING")) | "- \(.commit.message | split("\n")[0])"')

# 统计数量
FEATURE_COUNT=$(echo "$FEATURES" | grep -c "^-" || echo "0")
BUG_FIX_COUNT=$(echo "$BUG_FIXES" | grep -c "^-" || echo "0")
ENHANCEMENT_COUNT=$(echo "$ENHANCEMENTS" | grep -c "^-" || echo "0")
BREAKING_COUNT=$(echo "$BREAKING_CHANGES" | grep -c "^-" || echo "0")

# 6. 生成 Release Notes
RELEASE_NOTES="# 🎉 Release $NEW_VERSION

## 📊 变更统计
- **新功能**: $FEATURE_COUNT 个
- **Bug 修复**: $BUG_FIX_COUNT 个
- **功能改进**: $ENHANCEMENT_COUNT 个
- **破坏性变更**: $BREAKING_COUNT 个

## ✨ 新功能
$FEATURES

## 🐛 Bug 修复
$BUG_FIXES

## 🔧 功能改进
$ENHANCEMENTS

## ⚠️ 破坏性变更
$BREAKING_CHANGES

## 🙏 贡献者
感谢所有参与此版本开发的贡献者！

## 📥 安装
\`\`\`bash
npm install $OWNER/$REPO@$NEW_VERSION
\`\`\`

## 📚 文档
完整文档请查看: https://www.gitlink.org.cn/$OWNER/$REPO/wiki

---
**完整变更日志**: https://www.gitlink.org.cn/$OWNER/$REPO/compare/$PREV_VERSION...$NEW_VERSION"

# 7. 创建 Release
echo "创建 Release $NEW_VERSION..."
gitlink-cli release +create --owner $OWNER --repo $REPO \
  --tag $NEW_VERSION --name "$NEW_VERSION" --body "$RELEASE_NOTES"

echo "Release $NEW_VERSION 创建完成！"
```

## AI Agent 集成示例

Claude Code 等 AI Agent 可以深度集成此工作流：

```python
# 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 模板

### 标准模板

```markdown
# 🎉 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 标签的自动分类：

```python
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 完整性检查
- [ ] 变更统计准确性验证
- [ ] 破坏性变更标识
- [ ] 升级指南完整性
- [ ] 文档链接正确性
- [ ] 安装指令有效性
- [ ] 贡献者列表完整性

## 最佳实践

1. **定期发布**：建立定期发布节奏
2. **变更追踪**：确保所有变更都被记录
3. **清晰分类**：使用明确的分类和标签
4. **用户友好**：提供升级指南和迁移说明
5. **版本规范**：遵循语义化版本规范

## References

- [workflow-issue-triage](workflow-issue-triage.md) — Issue 分类工作流
- [workflow-pr-review](workflow-pr-review.md) — PR 审查工作流
- [gitlink-workflow](../SKILL.md) — 工作流总览
- [gitlink-shared](../../gitlink-shared/SKILL.md) — 认证和全局参数
- [release +create](../../gitlink-release/references/gitlink-release-create.md) — 创建 Release
- [release +list](../../gitlink-release/references/gitlink-release-list.md) — 列出 Release
