diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bda039b..2991478 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,44 @@ permissions: contents: write jobs: + test: + name: 发布前检查 + runs-on: ubuntu-latest + steps: + - name: 拉取源代码 + uses: actions/checkout@v4 + + - name: 安装 Go 环境 + uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache-dependency-path: './backend/go.sum' + + - name: 后端代码检查 + run: go vet ./... + working-directory: ./backend + + - name: 后端编译检查 + run: go build ./... + working-directory: ./backend + + - name: 安装 Node.js 环境 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + cache-dependency-path: './desktop/package-lock.json' + + - name: 安装前端依赖 + run: npm ci + working-directory: ./desktop + + - name: 前端构建检查 + run: npm run build + working-directory: ./desktop + build-and-release: + needs: test name: 构建并发布 - ${{ matrix.name }} strategy: fail-fast: false @@ -88,59 +125,7 @@ jobs: - name: 生成 Release Notes id: release_notes shell: bash - run: | - # 获取上一个 tag,如果不存在则获取第一个 commit - PREV_TAG=$(git describe --tags --abbrev=0 ${{ github.ref_name }}^ 2>/dev/null || git rev-list --max-parents=0 HEAD) - echo "Previous tag: $PREV_TAG" - - # 提取 commit 记录(不包括 merge commit) - # --no-merges: 只显示实际代码变更的 commit,过滤掉 PR merge 产生的合并提交 - LOGS=$(git log $PREV_TAG..${{ github.ref_name }} --pretty=format:"%s" --no-merges) - - # 初始化分类内容 - FEATS="" - FIXES="" - DOCS="" - OTHERS="" - - # 按前缀归类 - while IFS= read -r line; do - [ -z "$line" ] && continue - - # 清理可能导致 Markdown 渲染问题的特殊字符(如反斜杠、反引号等) - # 这里简单处理,保证基础展示正常 - clean_line=$(echo "$line" | sed 's/\\/\\\\/g; s/`/\\`/g') - - if [[ $line =~ ^feat ]]; then - FEATS="$FEATS\n- ${clean_line#feat: }" - elif [[ $line =~ ^fix ]]; then - FIXES="$FIXES\n- ${clean_line#fix: }" - elif [[ $line =~ ^docs ]]; then - DOCS="$DOCS\n- ${clean_line#docs: }" - elif [[ $line =~ ^refactor ]] || [[ $line =~ ^perf ]]; then - FIXES="$FIXES\n- ${clean_line}" - elif [[ $line =~ ^bump ]]; then - OTHERS="$OTHERS\n- ${clean_line}" - else - OTHERS="$OTHERS\n- ${clean_line}" - fi - done <<< "$LOGS" - - # 组合最终正文 - BODY="" - [ -n "$FEATS" ] && BODY="$BODY\n### 🚀 新功能 (Features)$FEATS\n" - [ -n "$FIXES" ] && BODY="$BODY\n### 🔧 修复与优化 (Bug Fixes & Refactor)$FIXES\n" - [ -n "$DOCS" ] && BODY="$BODY\n### 📝 文档更新 (Documentation)$DOCS\n" - [ -n "$OTHERS" ] && BODY="$BODY\n### 📦 其他改动 (Others)$OTHERS\n" - - [ -z "$BODY" ] && BODY="本次发布包含内部优化与稳定性提升。" - - # 处理换行符并存入环境变量(使用多行模式) - { - echo "body<> "$GITHUB_OUTPUT" + run: bash scripts/generate-changelog.sh "${{ github.ref_name }}" "https://github.com/${{ github.repository }}" >> "$GITHUB_OUTPUT" - name: 准备 Go 边车程序 shell: bash @@ -218,7 +203,6 @@ jobs: releaseBody: | ## 🎨 大香蕉 AI - 创作从未如此简单 - ### 🚀 本次更新 ${{ steps.release_notes.outputs.body }} ### 📦 包含组件 @@ -245,7 +229,6 @@ jobs: releaseBody: | ## 🎨 大香蕉 AI - 创作从未如此简单 - ### 🚀 本次更新 ${{ steps.release_notes.outputs.body }} ### 📦 包含组件 @@ -341,7 +324,6 @@ jobs: releaseBody: | ## 🎨 大香蕉 AI - 创作从未如此简单 - ### 🚀 本次更新 ${{ steps.release_notes.outputs.body }} ### 📦 包含组件 diff --git a/scripts/generate-changelog.sh b/scripts/generate-changelog.sh new file mode 100755 index 0000000..aa92e5d --- /dev/null +++ b/scripts/generate-changelog.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env bash +# 用法: ./scripts/generate-changelog.sh [repo_url] +# 输出 GITHUB_OUTPUT 多行格式: body</dev/null || git rev-list --max-parents=0 HEAD) +echo "Previous tag: $PREV_TAG" >&2 + +CHANGED_FILES=$(git diff --name-only "$PREV_TAG".."$CURRENT_TAG" 2>/dev/null || true) + +SUMMARY="" +# 检测变更文件是否匹配指定路径模式 +touches() { + printf "%s\n" "$CHANGED_FILES" | grep -qE "$1" +} + +if touches "backend/internal/provider/"; then + SUMMARY="${SUMMARY} +- AI 提供商接口适配与模型支持更新" +fi +if touches "backend/internal/worker/"; then + SUMMARY="${SUMMARY} +- 任务并发处理引擎优化" +fi +if touches "backend/internal/templates/"; then + SUMMARY="${SUMMARY} +- 模板市场资源更新" +fi +if touches "backend/internal/promptopt/"; then + SUMMARY="${SUMMARY} +- 提示词智能优化引擎改进" +fi +if touches "backend/internal/(storage|config|folder)/"; then + SUMMARY="${SUMMARY} +- 本地存储与配置管理优化" +fi +if touches "backend/internal/api/"; then + SUMMARY="${SUMMARY} +- 后端 API 接口调整" +fi +if touches "desktop/src/components/"; then + SUMMARY="${SUMMARY} +- 前端界面交互与组件体验升级" +fi +if touches "desktop/src/store/"; then + SUMMARY="${SUMMARY} +- 前端状态管理逻辑更新" +fi +if touches "desktop/src/services/"; then + SUMMARY="${SUMMARY} +- 前端 API 服务层调整" +fi +if touches "desktop/src-tauri/"; then + SUMMARY="${SUMMARY} +- 桌面端 Tauri 容器与权限配置更新" +fi +if touches "desktop/src/i18n/"; then + SUMMARY="${SUMMARY} +- 多语言国际化翻译更新" +fi +if touches "docker|Dockerfile|docker-compose|\.env\.example"; then + SUMMARY="${SUMMARY} +- Docker 部署方案优化" +fi +if touches "\.github/"; then + SUMMARY="${SUMMARY} +- CI/CD 构建与发布流程改进" +fi + +NOISE_REGEX='^(chore|ci|release|bump|test|ignore)(\(|:|!|:)' +LOGS=$(git log "$PREV_TAG".."$CURRENT_TAG" --pretty=format:"%s" --no-merges 2>/dev/null || true) + +FEATS="" +FIXES="" +DOCS="" +OTHERS="" + +while IFS= read -r line; do + [ -z "$line" ] && continue + [[ $line =~ $NOISE_REGEX ]] && continue + + clean_line=$(printf "%s" "$line" | sed 's/`/\\`/g') + + # 剥离 conventional commit 前缀: feat: / feat(scope): / feat(scope)!: / fix!: 等 + stripped_line=$(printf "%s" "$clean_line" | sed -E 's/^[a-z]+(\([^)]*\))?!?:[[:space:]]*//') + + if [[ $line =~ ^feat ]]; then + FEATS="$FEATS +- ${stripped_line}" + elif [[ $line =~ ^fix ]]; then + FIXES="$FIXES +- ${stripped_line}" + elif [[ $line =~ ^docs ]]; then + DOCS="$DOCS +- ${stripped_line}" + elif [[ $line =~ ^refactor ]] || [[ $line =~ ^perf ]]; then + FIXES="$FIXES +- ${clean_line}" + else + OTHERS="$OTHERS +- ${clean_line}" + fi +done <<< "$LOGS" + +BODY="" +if [ -n "$SUMMARY" ]; then + BODY="${BODY} +### 📋 更新概要 + +本次发布主要涉及以下模块:${SUMMARY} +" +fi + +[ -n "$FEATS" ] && BODY="${BODY} + +### 🚀 新功能 (Features)${FEATS} +" +[ -n "$FIXES" ] && BODY="${BODY} + +### 🔧 修复与优化 (Bug Fixes & Refactor)${FIXES} +" +[ -n "$DOCS" ] && BODY="${BODY} + +### 📝 文档更新 (Documentation)${DOCS} +" +[ -n "$OTHERS" ] && BODY="${BODY} + +### 📦 其他改动 (Others)${OTHERS} +" + +[ -z "$BODY" ] && BODY="本次发布包含内部优化与稳定性提升。" + +if [ -n "$REPO_URL" ] && [ "$PREV_TAG" != "$CURRENT_TAG" ]; then + BODY="${BODY} + +**Full Changelog**: ${REPO_URL}/compare/${PREV_TAG}...${CURRENT_TAG}" +fi + +{ + printf "%s\n" "body<