diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d078b75a..ca5eaa3f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,9 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true - name: Release version id: release_version @@ -66,6 +69,77 @@ jobs: cache-from: type=gha, scope=${{ github.workflow }}-docker cache-to: type=gha, scope=${{ github.workflow }}-docker + - name: Generate Changelog + id: changelog + run: | + # 获取上一个 tag(排除当前版本的 tag) + PREVIOUS_TAG=$(git tag -l 'v*' --sort=-v:refname | grep -v "^v${{ env.app_version }}$" | head -n 1) + echo "Previous tag: $PREVIOUS_TAG" + + if [ -z "$PREVIOUS_TAG" ]; then + # 没有上一个 tag,获取所有 commit + COMMITS=$(git log --pretty=format:"%s" HEAD) + else + # 获取上一个 tag 到当前 HEAD 之间的 commit + COMMITS=$(git log --pretty=format:"%s" ${PREVIOUS_TAG}..HEAD) + fi + + # 分类收集 commit 消息 + FEATURES="" + FIXES="" + OTHERS="" + + while IFS= read -r line; do + # 跳过空行、Merge commit 和版本更新 commit + if [ -z "$line" ]; then + continue + fi + if echo "$line" | grep -qE "^Merge pull request|^Merge branch|^更新 version"; then + continue + fi + + # 按 Conventional Commits 前缀分类 + if echo "$line" | grep -qiE "^feat(\(.+\))?:"; then + # 去掉前缀,保留描述 + desc=$(echo "$line" | sed -E 's/^feat(\([^)]*\))?:\s*//') + FEATURES="${FEATURES}- ${desc}\n" + elif echo "$line" | grep -qiE "^fix(\(.+\))?:"; then + desc=$(echo "$line" | sed -E 's/^fix(\([^)]*\))?:\s*//') + FIXES="${FIXES}- ${desc}\n" + elif echo "$line" | grep -qiE "^(docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?:"; then + desc=$(echo "$line" | sed -E 's/^(docs|style|refactor|perf|test|build|ci|chore|revert)(\([^)]*\))?:\s*//') + OTHERS="${OTHERS}- ${desc}\n" + else + # 没有前缀的 commit(如中文描述) + OTHERS="${OTHERS}- ${line}\n" + fi + done <<< "$COMMITS" + + # 组装 changelog + CHANGELOG="" + + if [ -n "$FEATURES" ]; then + CHANGELOG="${CHANGELOG}### ✨ 新功能\n\n${FEATURES}\n" + fi + + if [ -n "$FIXES" ]; then + CHANGELOG="${CHANGELOG}### 🐛 修复\n\n${FIXES}\n" + fi + + if [ -n "$OTHERS" ]; then + CHANGELOG="${CHANGELOG}### 🔧 其他\n\n${OTHERS}\n" + fi + + # 添加版本对比链接 + if [ -n "$PREVIOUS_TAG" ]; then + CHANGELOG="${CHANGELOG}**完整更新记录**: https://github.com/${{ github.repository }}/compare/${PREVIOUS_TAG}...v${{ env.app_version }}" + fi + + # 写入环境变量 + echo "CHANGELOG<> $GITHUB_ENV + echo -e "$CHANGELOG" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + - name: Get existing release body id: get_release_body continue-on-error: true @@ -73,9 +147,17 @@ jobs: release_body=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/${{ github.repository }}/releases/tags/v${{ env.app_version }}" | \ jq -r '.body // ""') - echo "RELEASE_BODY<> $GITHUB_ENV - echo "$release_body" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV + + # 如果已有手动编写的 release body,则保留;否则使用自动生成的 changelog + if [ -n "$release_body" ] && [ "$release_body" != "null" ] && [ "$release_body" != "" ]; then + echo "RELEASE_BODY<> $GITHUB_ENV + echo "$release_body" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + else + echo "RELEASE_BODY<> $GITHUB_ENV + echo "${{ env.CHANGELOG }}" >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + fi - name: Delete Release uses: dev-drprasad/delete-tag-and-release@v1.1