update-changelog.sh 3.42 KB
#!/bin/bash

# ============================================
# CHANGELOG 自动更新脚本
# ============================================
#
# 功能:根据 commit message 自动更新 docs/CHANGELOG.md
# 使用:在 commit-msg hook 中调用
#
# 作者:Claude Code
# 日期:2026-02-22
# ============================================

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 参数
COMMIT_MSG_FILE=$1
CHANGELOG_FILE="docs/CHANGELOG.md"

# 检查文件是否存在
if [ ! -f "$CHANGELOG_FILE" ]; then
    echo "  ${YELLOW}⚠️  CHANGELOG.md 不存在,跳过自动更新${NC}"
    exit 0
fi

# 读取 commit message
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# 解析 commit message
# 格式: type(scope): subject
if ! echo "$COMMIT_MSG" | grep -qE "^([a-z]+)\(([a-z-]+)\): .{1,50}"; then
    echo "  ${YELLOW}⚠️  Commit message 格式不匹配,跳过自动更新${NC}"
    exit 0
fi

# 提取信息
COMMIT_TYPE=$(echo "$COMMIT_MSG" | sed -E 's/^([a-z]+)\(.*/\1/')
COMMIT_SCOPE=$(echo "$COMMIT_MSG" | sed -E 's/^[a-z]+\(([a-z-]+)\).*/\1/')
COMMIT_SUBJECT=$(echo "$COMMIT_MSG" | sed -E 's/^[a-z]+\([a-z-]+\): (.{1,50}).*/\1/')

# 类型映射到中文
case "$COMMIT_TYPE" in
    feat)
        CHANGE_TYPE="新增"
        ;;
    fix)
        CHANGE_TYPE="修复"
        ;;
    docs)
        CHANGE_TYPE="文档"
        ;;
    style)
        CHANGE_TYPE="样式"
        ;;
    refactor)
        CHANGE_TYPE="优化"
        ;;
    perf)
        CHANGE_TYPE="性能"
        ;;
    test)
        CHANGE_TYPE="测试"
        ;;
    chore)
        CHANGE_TYPE="配置"
        ;;
    revert)
        CHANGE_TYPE="回滚"
        ;;
    *)
        CHANGE_TYPE="其他"
        ;;
esac

# 获取当前日期
TODAY=$(date +%Y-%m-%d)

# 获取影响的文件
STAGED_FILES=$(git diff --cached --name-only | head -5 | tr '\n' ', ' | sed 's/, $//')
if [ -z "$STAGED_FILES" ]; then
    STAGED_FILES="无"
fi

# 生成 CHANGELOG 条目
CHANGELOG_ENTRY="## [$TODAY] - $COMMIT_SUBJECT

### $CHANGE_TYPE
- $COMMIT_SUBJECT$COMMIT_SCOPE

---

**详细信息**
- **影响文件**: $STAGED_FILES
- **技术栈**: Taro 4, Vue 3, NutUI
- **测试状态**: 待验证
- **备注**: 自动生成

"

# 检查今天是否已有相同标题的条目
if grep -q "## \[$TODAY\] - $COMMIT_SUBJECT" "$CHANGELOG_FILE"; then
    echo "  ${YELLOW}⚠️  CHANGELOG 中已存在今日相同条目,跳过${NC}"
    exit 0
fi

# 创建临时文件
TEMP_FILE=$(mktemp)

# 将新条目插入到文件开头(跳过可能的文件头注释)
# 找到第一个 ## [ 开头的行,在它之前插入
if grep -q "^## \[" "$CHANGELOG_FILE"; then
    # 找到第一个条目的行号
    FIRST_ENTRY_LINE=$(grep -n "^## \[" "$CHANGELOG_FILE" | head -1 | cut -d: -f1)

    # 将新条目和原有内容合并
    head -n $((FIRST_ENTRY_LINE - 1)) "$CHANGELOG_FILE" > "$TEMP_FILE"
    echo "$CHANGELOG_ENTRY" >> "$TEMP_FILE"
    tail -n +$FIRST_ENTRY_LINE "$CHANGELOG_FILE" >> "$TEMP_FILE"
else
    # 如果没有找到条目,直接追加
    cat "$CHANGELOG_FILE" > "$TEMP_FILE"
    echo "$CHANGELOG_ENTRY" >> "$TEMP_FILE"
fi

# 替换原文件
mv "$TEMP_FILE" "$CHANGELOG_FILE"

# 将 CHANGELOG.md 加入暂存区
git add "$CHANGELOG_FILE"

echo "  ${GREEN}✅ CHANGELOG.md 已自动更新${NC}"
echo "  ${BLUE}   类型: $CHANGE_TYPE${NC}"
echo "  ${BLUE}   范围: $COMMIT_SCOPE${NC}"
echo "  ${BLUE}   描述: $COMMIT_SUBJECT${NC}"