Skip to content

Commit 7082f55

Browse files
authored
feat: improve release workflow with test gate, changelog script and smart summary (#55)
* feat: improve release workflow with test gate, changelog script and smart summary - Extract inline changelog shell into scripts/generate-changelog.sh - Add test job (go vet, go build, npm ci, npm run build) before release - Filter noise commits (chore/ci/release/bump/test/ignore) from notes - Add Full Changelog diff link at release notes bottom - Add path-based smart summary (detects changed modules automatically) * fix: address code review feedback on changelog script - Replace echo with printf for robustness with special characters - Fix scoped conventional commit prefix stripping (feat(scope):) - Use POSIX [[:space:]] instead of \s for BSD sed compatibility - Replace echo -e with printf for safe output
1 parent 7a40c1a commit 7082f55

2 files changed

Lines changed: 184 additions & 56 deletions

File tree

.github/workflows/release.yml

Lines changed: 38 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,44 @@ permissions:
88
contents: write
99

1010
jobs:
11+
test:
12+
name: 发布前检查
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: 拉取源代码
16+
uses: actions/checkout@v4
17+
18+
- name: 安装 Go 环境
19+
uses: actions/setup-go@v5
20+
with:
21+
go-version: '1.21'
22+
cache-dependency-path: './backend/go.sum'
23+
24+
- name: 后端代码检查
25+
run: go vet ./...
26+
working-directory: ./backend
27+
28+
- name: 后端编译检查
29+
run: go build ./...
30+
working-directory: ./backend
31+
32+
- name: 安装 Node.js 环境
33+
uses: actions/setup-node@v4
34+
with:
35+
node-version: 20
36+
cache: 'npm'
37+
cache-dependency-path: './desktop/package-lock.json'
38+
39+
- name: 安装前端依赖
40+
run: npm ci
41+
working-directory: ./desktop
42+
43+
- name: 前端构建检查
44+
run: npm run build
45+
working-directory: ./desktop
46+
1147
build-and-release:
48+
needs: test
1249
name: 构建并发布 - ${{ matrix.name }}
1350
strategy:
1451
fail-fast: false
@@ -88,59 +125,7 @@ jobs:
88125
- name: 生成 Release Notes
89126
id: release_notes
90127
shell: bash
91-
run: |
92-
# 获取上一个 tag,如果不存在则获取第一个 commit
93-
PREV_TAG=$(git describe --tags --abbrev=0 ${{ github.ref_name }}^ 2>/dev/null || git rev-list --max-parents=0 HEAD)
94-
echo "Previous tag: $PREV_TAG"
95-
96-
# 提取 commit 记录(不包括 merge commit)
97-
# --no-merges: 只显示实际代码变更的 commit,过滤掉 PR merge 产生的合并提交
98-
LOGS=$(git log $PREV_TAG..${{ github.ref_name }} --pretty=format:"%s" --no-merges)
99-
100-
# 初始化分类内容
101-
FEATS=""
102-
FIXES=""
103-
DOCS=""
104-
OTHERS=""
105-
106-
# 按前缀归类
107-
while IFS= read -r line; do
108-
[ -z "$line" ] && continue
109-
110-
# 清理可能导致 Markdown 渲染问题的特殊字符(如反斜杠、反引号等)
111-
# 这里简单处理,保证基础展示正常
112-
clean_line=$(echo "$line" | sed 's/\\/\\\\/g; s/`/\\`/g')
113-
114-
if [[ $line =~ ^feat ]]; then
115-
FEATS="$FEATS\n- ${clean_line#feat: }"
116-
elif [[ $line =~ ^fix ]]; then
117-
FIXES="$FIXES\n- ${clean_line#fix: }"
118-
elif [[ $line =~ ^docs ]]; then
119-
DOCS="$DOCS\n- ${clean_line#docs: }"
120-
elif [[ $line =~ ^refactor ]] || [[ $line =~ ^perf ]]; then
121-
FIXES="$FIXES\n- ${clean_line}"
122-
elif [[ $line =~ ^bump ]]; then
123-
OTHERS="$OTHERS\n- ${clean_line}"
124-
else
125-
OTHERS="$OTHERS\n- ${clean_line}"
126-
fi
127-
done <<< "$LOGS"
128-
129-
# 组合最终正文
130-
BODY=""
131-
[ -n "$FEATS" ] && BODY="$BODY\n### 🚀 新功能 (Features)$FEATS\n"
132-
[ -n "$FIXES" ] && BODY="$BODY\n### 🔧 修复与优化 (Bug Fixes & Refactor)$FIXES\n"
133-
[ -n "$DOCS" ] && BODY="$BODY\n### 📝 文档更新 (Documentation)$DOCS\n"
134-
[ -n "$OTHERS" ] && BODY="$BODY\n### 📦 其他改动 (Others)$OTHERS\n"
135-
136-
[ -z "$BODY" ] && BODY="本次发布包含内部优化与稳定性提升。"
137-
138-
# 处理换行符并存入环境变量(使用多行模式)
139-
{
140-
echo "body<<EOF"
141-
echo -e "$BODY"
142-
echo "EOF"
143-
} >> "$GITHUB_OUTPUT"
128+
run: bash scripts/generate-changelog.sh "${{ github.ref_name }}" "https://github.com/${{ github.repository }}" >> "$GITHUB_OUTPUT"
144129

145130
- name: 准备 Go 边车程序
146131
shell: bash
@@ -218,7 +203,6 @@ jobs:
218203
releaseBody: |
219204
## 🎨 大香蕉 AI - 创作从未如此简单
220205
221-
### 🚀 本次更新
222206
${{ steps.release_notes.outputs.body }}
223207
224208
### 📦 包含组件
@@ -245,7 +229,6 @@ jobs:
245229
releaseBody: |
246230
## 🎨 大香蕉 AI - 创作从未如此简单
247231
248-
### 🚀 本次更新
249232
${{ steps.release_notes.outputs.body }}
250233
251234
### 📦 包含组件
@@ -341,7 +324,6 @@ jobs:
341324
releaseBody: |
342325
## 🎨 大香蕉 AI - 创作从未如此简单
343326
344-
### 🚀 本次更新
345327
${{ steps.release_notes.outputs.body }}
346328
347329
### 📦 包含组件

scripts/generate-changelog.sh

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/usr/bin/env bash
2+
# 用法: ./scripts/generate-changelog.sh <current_tag> [repo_url]
3+
# 输出 GITHUB_OUTPUT 多行格式: body<<EOF ... EOF
4+
set -euo pipefail
5+
6+
CURRENT_TAG="${1:?Usage: $0 <current_tag> [repo_url]}"
7+
REPO_URL="${2:-}"
8+
9+
PREV_TAG=$(git describe --tags --abbrev=0 "$CURRENT_TAG^" 2>/dev/null || git rev-list --max-parents=0 HEAD)
10+
echo "Previous tag: $PREV_TAG" >&2
11+
12+
CHANGED_FILES=$(git diff --name-only "$PREV_TAG".."$CURRENT_TAG" 2>/dev/null || true)
13+
14+
SUMMARY=""
15+
# 检测变更文件是否匹配指定路径模式
16+
touches() {
17+
printf "%s\n" "$CHANGED_FILES" | grep -qE "$1"
18+
}
19+
20+
if touches "backend/internal/provider/"; then
21+
SUMMARY="${SUMMARY}
22+
- AI 提供商接口适配与模型支持更新"
23+
fi
24+
if touches "backend/internal/worker/"; then
25+
SUMMARY="${SUMMARY}
26+
- 任务并发处理引擎优化"
27+
fi
28+
if touches "backend/internal/templates/"; then
29+
SUMMARY="${SUMMARY}
30+
- 模板市场资源更新"
31+
fi
32+
if touches "backend/internal/promptopt/"; then
33+
SUMMARY="${SUMMARY}
34+
- 提示词智能优化引擎改进"
35+
fi
36+
if touches "backend/internal/(storage|config|folder)/"; then
37+
SUMMARY="${SUMMARY}
38+
- 本地存储与配置管理优化"
39+
fi
40+
if touches "backend/internal/api/"; then
41+
SUMMARY="${SUMMARY}
42+
- 后端 API 接口调整"
43+
fi
44+
if touches "desktop/src/components/"; then
45+
SUMMARY="${SUMMARY}
46+
- 前端界面交互与组件体验升级"
47+
fi
48+
if touches "desktop/src/store/"; then
49+
SUMMARY="${SUMMARY}
50+
- 前端状态管理逻辑更新"
51+
fi
52+
if touches "desktop/src/services/"; then
53+
SUMMARY="${SUMMARY}
54+
- 前端 API 服务层调整"
55+
fi
56+
if touches "desktop/src-tauri/"; then
57+
SUMMARY="${SUMMARY}
58+
- 桌面端 Tauri 容器与权限配置更新"
59+
fi
60+
if touches "desktop/src/i18n/"; then
61+
SUMMARY="${SUMMARY}
62+
- 多语言国际化翻译更新"
63+
fi
64+
if touches "docker|Dockerfile|docker-compose|\.env\.example"; then
65+
SUMMARY="${SUMMARY}
66+
- Docker 部署方案优化"
67+
fi
68+
if touches "\.github/"; then
69+
SUMMARY="${SUMMARY}
70+
- CI/CD 构建与发布流程改进"
71+
fi
72+
73+
NOISE_REGEX='^(chore|ci|release|bump|test|ignore)(\(|:|!|:)'
74+
LOGS=$(git log "$PREV_TAG".."$CURRENT_TAG" --pretty=format:"%s" --no-merges 2>/dev/null || true)
75+
76+
FEATS=""
77+
FIXES=""
78+
DOCS=""
79+
OTHERS=""
80+
81+
while IFS= read -r line; do
82+
[ -z "$line" ] && continue
83+
[[ $line =~ $NOISE_REGEX ]] && continue
84+
85+
clean_line=$(printf "%s" "$line" | sed 's/`/\\`/g')
86+
87+
# 剥离 conventional commit 前缀: feat: / feat(scope): / feat(scope)!: / fix!: 等
88+
stripped_line=$(printf "%s" "$clean_line" | sed -E 's/^[a-z]+(\([^)]*\))?!?:[[:space:]]*//')
89+
90+
if [[ $line =~ ^feat ]]; then
91+
FEATS="$FEATS
92+
- ${stripped_line}"
93+
elif [[ $line =~ ^fix ]]; then
94+
FIXES="$FIXES
95+
- ${stripped_line}"
96+
elif [[ $line =~ ^docs ]]; then
97+
DOCS="$DOCS
98+
- ${stripped_line}"
99+
elif [[ $line =~ ^refactor ]] || [[ $line =~ ^perf ]]; then
100+
FIXES="$FIXES
101+
- ${clean_line}"
102+
else
103+
OTHERS="$OTHERS
104+
- ${clean_line}"
105+
fi
106+
done <<< "$LOGS"
107+
108+
BODY=""
109+
if [ -n "$SUMMARY" ]; then
110+
BODY="${BODY}
111+
### 📋 更新概要
112+
113+
本次发布主要涉及以下模块:${SUMMARY}
114+
"
115+
fi
116+
117+
[ -n "$FEATS" ] && BODY="${BODY}
118+
119+
### 🚀 新功能 (Features)${FEATS}
120+
"
121+
[ -n "$FIXES" ] && BODY="${BODY}
122+
123+
### 🔧 修复与优化 (Bug Fixes & Refactor)${FIXES}
124+
"
125+
[ -n "$DOCS" ] && BODY="${BODY}
126+
127+
### 📝 文档更新 (Documentation)${DOCS}
128+
"
129+
[ -n "$OTHERS" ] && BODY="${BODY}
130+
131+
### 📦 其他改动 (Others)${OTHERS}
132+
"
133+
134+
[ -z "$BODY" ] && BODY="本次发布包含内部优化与稳定性提升。"
135+
136+
if [ -n "$REPO_URL" ] && [ "$PREV_TAG" != "$CURRENT_TAG" ]; then
137+
BODY="${BODY}
138+
139+
**Full Changelog**: ${REPO_URL}/compare/${PREV_TAG}...${CURRENT_TAG}"
140+
fi
141+
142+
{
143+
printf "%s\n" "body<<EOF"
144+
printf "%s\n" "$BODY"
145+
printf "%s\n" "EOF"
146+
}

0 commit comments

Comments
 (0)