docs(changelog): distill release notes and add platform grouping

The v2.5.4 notes had grown to 97 free-form entries exposed verbatim in
the in-app update dialog. Distill them to 58 one-theme-per-line entries
capped at ~60 CJK characters with no internal terminology, and move the
writing rules into template/Changelog.md so every cycle starts from them.

Release plumbing now agrees on the --- divider: extract_update_logs.sh
stops there like updatelog.mjs, so file-only content never reaches
release bodies, while updater.mjs appends a per-tag See More link to the
update notes it generates. scripts-workflow/group_platforms.sh locks
platform entries under emoji platform headings, wired into pre-commit,
release and autobuild CI, and the changelog bump script; AGENTS.md points
agents at the template rules.
This commit is contained in:
Tunglies
2026-09-10 08:09:54 +08:00
parent 8812923eda
commit f77f60ecd5
10 changed files with 246 additions and 94 deletions
+6
View File
@@ -35,6 +35,9 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v7 uses: actions/checkout@v7
- name: Group changelog platforms
run: bash ./scripts-workflow/group_platforms.sh
- name: Fetch UPDATE logs - name: Fetch UPDATE logs
id: fetch_update_logs id: fetch_update_logs
run: bash ./scripts/extract_update_logs.sh run: bash ./scripts/extract_update_logs.sh
@@ -510,6 +513,9 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v7 uses: actions/checkout@v7
- name: Group changelog platforms
run: bash ./scripts-workflow/group_platforms.sh
- name: Fetch UPDATE logs - name: Fetch UPDATE logs
id: fetch_update_logs id: fetch_update_logs
run: bash ./scripts/extract_update_logs.sh run: bash ./scripts/extract_update_logs.sh
+6
View File
@@ -92,6 +92,9 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v7 uses: actions/checkout@v7
- name: Group changelog platforms
run: bash ./scripts-workflow/group_platforms.sh
- name: Fetch UPDATE logs - name: Fetch UPDATE logs
id: fetch_update_logs id: fetch_update_logs
run: bash ./scripts/extract_update_logs.sh run: bash ./scripts/extract_update_logs.sh
@@ -624,6 +627,9 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v7 uses: actions/checkout@v7
- name: Group changelog platforms
run: bash ./scripts-workflow/group_platforms.sh
- name: Fetch UPDATE logs - name: Fetch UPDATE logs
id: fetch_update_logs id: fetch_update_logs
run: bash ./scripts/extract_update_logs.sh run: bash ./scripts/extract_update_logs.sh
+3
View File
@@ -55,6 +55,9 @@ the ownership evidence the AI-slop review evaluates (see
[pr-ai-slop-review.md](.github/workflows/pr-ai-slop-review.md) is compiled: [pr-ai-slop-review.md](.github/workflows/pr-ai-slop-review.md) is compiled:
after editing it, run `gh aw compile` and commit the regenerated after editing it, run `gh aw compile` and commit the regenerated
`pr-ai-slop-review.lock.yml`. Never edit the lock file directly. `pr-ai-slop-review.lock.yml`. Never edit the lock file directly.
11. **Changelog.** Entries follow the rules in
[`template/Changelog.md`](template/Changelog.md): one line per
user-visible change, no internals.
## Pull Request Shape ## Pull Request Shape
+71 -89
View File
@@ -1,73 +1,69 @@
## v2.5.4 ## v2.5.4
### 🐞 修复问题 <details>
<summary><strong> 🐞 修复问题 </strong></summary>
- 修复 macOS 多显示器切换时托盘速率样式不同步 - 修复系统代理状态不同步:切换失败后界面停留错误状态、后台应用后未刷新、托盘与热键切换失败无提示
- 修复 WebSocket 在 onConnected 初始化完成前被保存的问题,避免初始化失败后留下无监听且无法重试的无效连接。 - 修复代理守卫反复失败后无限重试且不告知用户的问题,连续失败后停止并告知
- 修复 Mihomo API 变更后 inline proxy-provider 被错误过滤的问题,解决节点显示 Unknown 及延迟测试失败的问题 - 修复其余系统代理问题:未开启过的用户每次启动收到报错、恢复备份后未关闭
- 修复 macOS 开启「访问系统范围设置需要管理员密码」时无法设置系统代理的问题 - 修复服务健康探测结果粘滞、受限机器上安装服务后无法切换服务模式,失败时回退 Sidecar 且开关状态与内核一致
- 修复从未开启过系统代理的用户,每次内核启动都收到报错的问题 - 修复服务模式下升级内核后重启仍运行旧版本的问题(需要 clash-verge-service 2.6.8)
- 修复受限机器上「安装服务 → 自动切换到服务模式」整条流程无法走通的问题 - 修复 Mihomo API 变更后 proxy-provider 被误过滤,节点显示 Unknown 及延迟测试失败
- 修复 Windows 卸载后保留 TUN 配置、重新安装时因系统服务缺失而无法启动内核的问题,启动时会在当前会话回退到 Sidecar,并保留原 TUN 偏好
- 修复系统代理开关切换失败后,界面停留在错误状态的问题
- 修复托盘与热键切换系统代理失败时没有任何提示的问题
- 修复代理守卫反复失败后无限重试且不告知用户的问题
- 修复错误提示只显示最外层信息、丢失具体原因的问题
- 修复过长的错误提示撑满界面的问题(右键复制仍为完整内容)
- 修复部分错误提示显示为 [object Object] 的问题
- 修复 i18n 清理脚本因导入方式错误而无法运行的问题
- 修复 Linux 桌面环境下主题切换时应用外观不跟随的问题
- 修复 Gemini 测试正确性
- 修复 macOS/Linux 用户模式下旧版服务遗留的 cache.db 属主为 root 且当前用户不可写,导致无法记住上次选择节点的问题
- 修复代理组节点 `PASS-RULE` 被过滤丢失的问题 - 修复代理组节点 `PASS-RULE` 被过滤丢失的问题
- 修复 Windows 主窗口打开时关机被「此程序正在阻止关机」卡住、无法退出的问题 - 修复内核启动后未恢复上次选择的节点、代理组回落到首个节点的问题
- 修复代理组与首页测试列表的内联 SVG 图标含中文等非 Latin-1 字符时无法显示、甚至导致页面报错的问题,改用 UTF-8 URL 编码渲染图标 - 修复代理组与首页测试列表图标在含非 Latin-1 字符时无法显示、导致页面报错的问题
- 修复内核启动后未恢复上次选择的节点、代理组回落到首个节点的问题,应用记录的节点选择会在内核就绪后重新应用,不再完全依赖内核的 cache.db
- 修复修改端口失败后 PAC 服务未重新开启,导致使用 PAC 的浏览器静默直连的问题
- 修复并发修改端口、TUN 等配置时草稿相互覆盖或被误回滚的问题 - 修复并发修改端口、TUN 等配置时草稿相互覆盖或被误回滚的问题
- 修复启动初始化时 Runtime 配置未应用、代理视图分组顺序使用旧配置的问题 - 修复快速重启内核时混合端口被错误回退的问题
- 修复刷新代理配置事件导致应用卡死的问题 - 修复修改端口失败后 PAC 服务未重新开启,导致使用 PAC 的浏览器静默直连的问题
- 修复关闭「自动检查更新」后首页手动检查更新直接提示已是最新版本的问题
- 修复订阅列表解析失败时孤立文件清理误删订阅文件的问题,订阅文件现在仅在显式删除时才会移除
- 修复删除订阅中途失败后配置与文件状态不一致的问题
- 修复无效的订阅排序请求导致订阅列表丢失的问题
- 修复订阅自动更新失败未上报的问题
- 修复重启应用后订阅自动更新倒计时被推迟并显示「更新失败」的问题,更新进行中被禁用的任务再次启用时不再重复执行
- 修复编辑含空名称节点的订阅时代理编辑器崩溃的问题
- 修复订阅编辑器在 YAML 格式错误时丢失原始内容的问题
- 修复 DNS 设置 YAML 编辑模式下空内容解析报错及初始值覆盖用户配置的问题
- 修复 TUN 模式下 `fake-ip-range6` 默认值,重置为 `2001:2::0/64` - 修复 TUN 模式下 `fake-ip-range6` 默认值,重置为 `2001:2::0/64`
- 修复回退到 Sidecar 后 TUN 开关仍显示已开启的问题,开关状态以内核实际运行状态为准 - 修复启动初始化时代理视图分组顺序使用旧配置的问题
- 修复服务健康探测结果粘滞、服务操作失败后未能回退到 Sidecar 的问题 - 修复刷新代理配置事件导致应用卡死的问题
- 修复服务模式下升级内核后重启仍运行旧版本内核的问题:升级后的内核经管理员授权交付给服务,安装包也会在安装时向服务登记内置内核(需要 clash-verge-service 2.6.8) - 修复订阅文件管理问题:解析失败时清理误删订阅文件、删除中途失败后状态不一致、无效排序请求导致列表丢失
- 修复 macOS 内核自更新被 Hardened Runtime 终止、留下 0 字节内核文件的问题,改为由应用下载校验后原子替换 - 修复订阅自动更新失败未上报、重启后倒计时被推迟并误显「更新失败」的问题
- 修复 Windows 内核升级重启失败后遗留旧内核文件、且卸载程序不清理的问题 - 修复订阅与 DNS 编辑器问题:空名称节点导致崩溃、YAML 错误时丢失原始内容、DNS 编辑初始值覆盖用户配置
- 修复 Windows 上数据目录属主为其他账户(如曾以管理员运行)导致服务模式无法使用的问题,启动时自动修复属主 - 修复关闭「自动检查更新」后首页手动检查更新直接提示已是最新版本的问题
- 改进错误提示:显示完整原因而非操作系统原文、不再出现 [object Object]、过长时截断(右键复制完整内容)
**🖥️ Windows**
- 修复 Windows 内核升级失败遗留旧内核且卸载不清理的问题
- 修复 Windows 数据目录属主异常导致服务模式不可用的问题,启动时自动修复属主
- 修复 Windows 对不支持的 redir/tproxy 端口误做冲突检测的问题
- 修复 Windows 上系统代理写入偶发瞬时失败的问题,增加重试并给出提示
- 修复 Windows 卸载后残留 TUN 配置、重装后无法启动内核,当前会话回退 Sidecar 并保留 TUN 偏好
- 修复 Windows 主窗口打开时关机被「此程序正在阻止关机」卡住、无法退出的问题
**🍎 macOS**
- 修复内核自更新在 macOS 留下 0 字节文件的问题
- 修复 macOS 系统代理写入:管理员密码下无法设置、登录自启时网络未就绪、无活动网络服务时误报失败
- 修复 macOS 多显示器切换时托盘速率样式不同步的问题
**🐧 Linux**
- 修复 Linux 通过 pkexec 安装/卸载服务时 polkit 认证失败的问题 - 修复 Linux 通过 pkexec 安装/卸载服务时 polkit 认证失败的问题
- 修复快速重启内核或 macOS 监听守卫误判导致混合端口被错误回退的问题 - 修复 Linux 桌面环境下主题切换时应用外观不跟随的问题
- 修复 Windows 上对不支持的 redir/tproxy 端口做冲突检测的问题
- 修复 macOS 登录自启时网络尚未就绪导致系统代理写入失败的问题,并在出现新网络服务时自动重新应用系统代理 **🍎/🐧 macOS/Linux**
- 修复 macOS 无活动网络服务时开关系统代理被当作失败的问题
- 修复 Windows 系统代理写入偶发瞬时失败的问题,增加重试并给出提示 - 修复系统代理绕过列表在 macOS/Linux 上使用错误分隔符的问题
- 修复内核尚未运行时开启系统代理没有明确提示、以及恢复备份后系统代理未按备份状态关闭的问题 - 修复 macOS/Linux 旧服务遗留数据属主为 root,导致无法记住选中节点的问题
- 修复后台自动应用系统代理后界面状态未刷新的问题
- 修复系统代理绕过列表在 Linux/macOS 上使用错误分隔符的问题 </details>
- 修复退出应用时关闭内核失败没有显示具体原因的问题
- 修复侧边栏菜单项字重不一致的问题
<details> <details>
<summary><strong> ✨ 新增功能 </strong></summary> <summary><strong> ✨ 新增功能 </strong></summary>
- 新增混合代理端口冲突自动回退:启动时检测端口占用并临时改用可用端口,配置中的端口保持不变、下次启动重新尝试,同时统一首页、设置与系统代理中的生效端口显示 - 新增混合代理端口冲突自动回退:启动时检测端口占用并临时改用可用端口,配置端口保持不变、下次启动重新尝试
- 系统代理或 TUN 因权限被拒时弹出引导窗口,一步安装系统服务并自动恢复原本的设置 - 系统代理或 TUN 因权限被拒时弹出引导窗口,一步安装系统服务并自动恢复原本设置,并显示当前阶段
- 引导窗口显示当前阶段:安装服务 / 重启内核 / 应用代理
- 系统代理失败会保留到窗口可见时再呈现,不会因窗口隐藏或最小化而丢失
- 区分「需要安装服务」与「服务已就绪但内核仍以 Sidecar 运行」,分别给出对应操作
- 支持手动点击取消代理组中固定的代理节点 - 支持手动点击取消代理组中固定的代理节点
- 开启 DNS 覆写时若当前订阅包含自定义 DNS 配置会先弹窗确认,订阅更新后检测到自定义 DNS 会自动关闭覆写,避免覆盖导致节点无法连接 - 开启 DNS 覆写时若当前订阅包含自定义 DNS 配置会先弹窗确认,订阅更新后自动关闭覆写,避免节点无法连接
- 代理页空状态给出排查引导(未导入或未激活订阅、内核不可用等),并提供前往订阅、重启内核、打开日志目录等快捷操作 - 代理页空状态给出排查引导(未导入或未激活订阅、内核不可用等),提供前往订阅、重启内核等快捷操作
- 订阅自动更新间隔低于 24 小时时给出警告,避免频繁重载内核中断连接 - 订阅自动更新间隔低于 24 小时时给出警告,避免频繁重载内核中断连接
- 启动失败时弹窗显示具体原因并写入 `logs/startup.log`,不再静默退出 - 启动失败时弹窗显示具体原因并写入 `logs/startup.log`,不再静默退出
**🍎 macOS**
- macOS 采用 Icon Composer 2 制作的 Liquid Glass 应用图标 - macOS 采用 Icon Composer 2 制作的 Liquid Glass 应用图标
</details> </details>
@@ -76,41 +72,27 @@
<summary><strong> 🚀 优化改进 </strong></summary> <summary><strong> 🚀 优化改进 </strong></summary>
- TUN 模式设置也遵循 原始配置 < Merge 覆写 < Script 脚本 < GUI - TUN 模式设置也遵循 原始配置 < Merge 覆写 < Script 脚本 < GUI
- 优化监听端口冲突检测:代理端口按最终 Runtime 监听范围校验并协调三层持久化,隧道按实际地址与 TCP/UDP 协议检测且保留热重载 - 增强代理页刷新、链路选择与异常状态下的稳定性
- 优化代理数据处理:统一通过单一 IPC 获取有序代理视图,并增强刷新、链路选择、重复判断及异常状态下的稳定性 - 加强服务多用户隔离与身份认证,新增旧版服务迁移引导
- 新增 macOS 启动门禁,避免多用户环境下的实例冲突 - 系统代理写入半途失败后,系统状态、代理守卫与配置保持一致
- 加强 Service 多用户隔离与身份认证,支持安全的 Owner 接管 - 优化内核启动、停止及更新流程,减少启动失败与残留进程;减少慢机器上误判服务不可用
- 统一系统代理所有权,实现原子化代理切换 - 优化首页当前节点的交互与固定状态显示
- 新增旧版 Service 迁移引导与 Sidecar 安全回退
- 优化核心启动、停止及更新流程,减少竞态与残留进程
- 优化首页当前节点的交互
- Linux 代理设置缺失必要命令时,给出明确命令缺失信息,避免模糊报错
- 支持在前置规则与后置规则之间直接切换规则位置 - 支持在前置规则与后置规则之间直接切换规则位置
- 系统代理已经是目标状态时不再执行多余的系统写入
- 系统代理写入半途失败后,系统状态、代理守卫与配置三者保持一致
- 代理守卫连续失败后停止并告知,不再静默重试
- TUN 模式开关不再需要单独的安装服务按钮,与系统代理走同一条恢复流程
- 系统代理失败给出可操作的具体原因,而非操作系统的英文原文
- 配置变更后统一广播刷新,界面开关与托盘状态保持同步
- 重构命令层错误返回为结构化格式,保留完整诊断链
- 优化首页界面中当前节点固定状态显示
- 优化拖动排序样式及动画效果
- Linux KDE 桌面环境设置系统代理时不再强制要求使用 `gsettings` 命令
- 移除便携模式支持,不再识别 `.config/PORTABLE` 标记,数据目录统一使用系统应用数据目录
- Linux 设置系统代理不再强制要求 `dconf` 命令
- 限制外部链接仅允许打开 http/https 地址,订阅主页地址同样校验 - 限制外部链接仅允许打开 http/https 地址,订阅主页地址同样校验
- 更新弹窗的发布说明经过安全过滤并支持 GFM 语法(表格、提示块),版本比较统一使用语义化版本 - 优化更新与安装体验:发布说明支持 GFM 渲染、自动更新跳过语言选择提示、内核校验被终止时提示检查安全软件
- 自动更新时跳过安装程序的语言选择提示 - 界面细节:搜索框自动聚焦、节点卡片不显示 provider 名称、统一字体与等宽编辑器、优化拖动排序动画
- 内核校验进程被终止时提示检查安全软件或 CPU 兼容性,内核启动、校验失败的文件缺失错误附带具体路径 - 停止内核前清理所有 WebSocket 连接、切换出站模式时批量关闭,修复初始化失败后留下无效连接的问题
- 放宽服务 IPC 调用超时,减少慢机器上误判服务不可用 - 性能优化:降低托盘速率、服务状态检查等后台开销与重复计算,页面切换不再显示加载状态
- 打开代理页搜索/筛选框时自动聚焦输入框,并更换筛选图标 - 日志系统重构:支持模块过滤与排除、减少噪音日志,修复切换日志配置时的资源泄漏
- 节点卡片不再显示 provider 名称 - 移除便携模式支持,不再识别 `.config/PORTABLE` 标记,数据目录统一使用系统应用数据目录
- 订阅卡片切换中的遮罩覆盖整张卡片
- 统一界面字体设置,编辑器统一使用等宽字体
- 停止内核前先清理所有 WebSocket 连接,切换出站模式时批量关闭连接
- 减少后台空闲开销(托盘速率、服务状态轮询)以及代理列表延迟排序、托盘菜单的重复计算
- 页面切换不再显示加载状态,减少重复的订阅列表刷新
- 日志系统重构:支持模块过滤与排除,以结构化 span 记录内核启动、代理应用、服务 IPC 等流程并去除噪音日志,修复切换日志配置时 Sidecar 日志写入器泄漏线程与文件句柄的问题
- 补全繁体中文后端字符串,改进俄语翻译,语言列表中的「中文」改为「简体中文」 - 补全繁体中文后端字符串,改进俄语翻译,语言列表中的「中文」改为「简体中文」
**🍎 macOS**
- 避免 macOS 多用户环境下同时启动多个实例
**🐧 Linux**
- 改进 Linux 系统代理兼容性:缺失命令时给出明确信息,KDE 下不再强制 `gsettings`、`dconf`
</details> </details>
+11
View File
@@ -118,6 +118,17 @@ end
# frontend checks # frontend checks
cm_run_task frontend-format cm_run_task frontend-format
# changelog platform grouping
has_changelog = exec git diff --cached --quiet -- Changelog.md
if eq ${has_changelog.code} 1
grouped = exec bash scripts-workflow/group_platforms.sh
if not eq ${grouped.code} 0
echo "Changelog platform grouping failed"
exit 1
end
exec git add Changelog.md
end
''' '''
[tasks.pre-push] [tasks.pre-push]
+2
View File
@@ -32,6 +32,8 @@ bak_ts=$(timestamp)
cp "$CHANGELOG" "$BACKUP_DIR/Changelog.md.bak.$bak_ts" cp "$CHANGELOG" "$BACKUP_DIR/Changelog.md.bak.$bak_ts"
echo "Backed up $CHANGELOG -> $BACKUP_DIR/Changelog.md.bak.$bak_ts" echo "Backed up $CHANGELOG -> $BACKUP_DIR/Changelog.md.bak.$bak_ts"
bash "$(dirname "$0")/group_platforms.sh"
if [ -f "$HISTORY" ]; then if [ -f "$HISTORY" ]; then
cp "$HISTORY" "$BACKUP_DIR/Changelog.history.md.bak.$bak_ts" cp "$HISTORY" "$BACKUP_DIR/Changelog.history.md.bak.$bak_ts"
echo "Backed up $HISTORY -> $BACKUP_DIR/Changelog.history.md.bak.$bak_ts" echo "Backed up $HISTORY -> $BACKUP_DIR/Changelog.history.md.bak.$bak_ts"
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env bash
set -euo pipefail
# group_platforms.sh — lock platform entries into platform subsections.
#
# Inside every <details> section of Changelog.md, entries whose platform
# mentions form a set of one or two platforms (Windows/macOS/Linux) are
# grouped under a bold heading named by that set (e.g. **macOS/Linux**),
# ordered Windows -> macOS -> Linux. Entries naming all three or none stay
# in the common area above the headings. Idempotent.
#
# usage: group_platforms.sh [--check]
# (default) rewrite Changelog.md in place
# --check report misplaced entries without writing; exit 1 if any
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
CHANGELOG="$ROOT_DIR/Changelog.md"
if [ ! -f "$CHANGELOG" ]; then
echo "Error: $CHANGELOG not found" >&2
exit 2
fi
regrouped=$(awk '
{ lines[NR] = $0 }
END {
n = NR; i = 1
while (i <= n) {
if (lines[i] ~ /^<details>$/) {
j = i
while (j < n && lines[j] !~ /^<\/details>$/) j++
emit_block(i, j)
i = j + 1
} else {
print lines[i]
i++
}
}
}
function platform_of(l, c, key) {
c = 0; key = ""
if (l ~ /Windows/) { c++; key = key "Windows/" }
if (l ~ /macOS/) { c++; key = key "macOS/" }
if (l ~ /Linux/) { c++; key = key "Linux/" }
if (c == 0 || c == 3) return ""
sub(/\/$/, "", key)
return key
}
function heading(kk, t) {
t = kk
gsub(/Windows/, "🖥️", t)
gsub(/macOS/, "🍎", t)
gsub(/Linux/, "🐧", t)
return "**" t " " kk "**"
}
function emit_block(a, b, k, m, n, x, oi, kk, nkeys, order, count, entries) {
split("", count); split("", entries)
print lines[a]
k = a + 1
if (lines[k] ~ /^<summary>/) { print lines[k]; k++ }
print ""
for (m = k; m < b; m++) {
l = lines[m]
if (l !~ /^- /) continue
p = platform_of(l)
# increment must not live inside the subscript expression:
# BSD awk parses `++count[p]` there as two unary pluses
n = ++count[p]
entries[p SUBSEP n] = l
}
for (x = 1; x <= count[""]; x++) print entries["" SUBSEP x]
nkeys = split("Windows macOS Linux Windows/macOS Windows/Linux macOS/Linux", order, " ")
for (oi = 1; oi <= nkeys; oi++) {
kk = order[oi]
if (!count[kk]) continue
print ""
print heading(kk)
print ""
for (x = 1; x <= count[kk]; x++) print entries[kk SUBSEP x]
}
print ""
print lines[b]
}
' "$CHANGELOG")
if [ "${1:-}" = "--check" ]; then
if [ "$regrouped" = "$(cat "$CHANGELOG")" ]; then
echo "OK: platform grouping is up to date"
exit 0
fi
echo "Misplaced platform entries detected. Diff (current -> regrouped):"
diff "$CHANGELOG" <(printf '%s\n' "$regrouped") || true
exit 1
fi
before=$(grep -c '^- ' "$CHANGELOG" || true)
after=$(printf '%s\n' "$regrouped" | grep -c '^- ' || true)
if [ "$before" != "$after" ]; then
echo "Error: regrouping would drop entries ($before -> $after); refusing to write" >&2
exit 4
fi
printf '%s\n' "$regrouped" > "$CHANGELOG"
echo "Regrouped platform entries in $CHANGELOG"
+6 -1
View File
@@ -13,12 +13,17 @@ if [[ ! -f "$CHANGELOG_FILE" ]]; then
exit 1 exit 1
fi fi
# 提取从第一个 '## v' 开始到下一个 '## v' 前的内容 # 提取从第一个 '## v' 开始到 '---' 或下一个 '## v' 前的内容
# '---' 与 scripts/updatelog.mjs 的解析一致:分隔线之后的内容
# 只属于仓库文件,不进入任何 release body
UPDATE_LOGS=$(awk ' UPDATE_LOGS=$(awk '
/^## v/ { /^## v/ {
if (found) exit; if (found) exit;
found=1 found=1
} }
/^---/ && found {
exit
}
found found
' "$CHANGELOG_FILE") ' "$CHANGELOG_FILE")
+6 -3
View File
@@ -72,11 +72,14 @@ async function processRelease(github, options, tag, isAlpha) {
tag: tag.name, tag: tag.name,
}) })
const notes = await resolveUpdateLog(tag.name).catch(() =>
resolveUpdateLogDefault().catch(() => 'No changelog available'),
)
const releaseUrl = `https://github.com/${options.owner}/${options.repo}/releases/tag/${tag.name}`
const updateData = { const updateData = {
name: tag.name, name: tag.name,
notes: await resolveUpdateLog(tag.name).catch(() => notes: `${notes}\n\n**[See More](${releaseUrl})**`,
resolveUpdateLogDefault().catch(() => 'No changelog available'),
),
pub_date: new Date().toISOString(), pub_date: new Date().toISOString(),
platforms: { platforms: {
// platform format: // platform format:
+25 -1
View File
@@ -1,6 +1,30 @@
<!-- Release-notes skeleton. Entries accumulate in ./Changelog.md as PRs land;
before publishing a release, distill them:
- user-visible changes only — no dev tooling, CI fixes, or refactors whose
effect is already covered by another entry
- describe outcomes, not internals: no internal module names, IPC or
protocol details, or implementation mechanics — write what the user
observes, not how the code achieves it
- one line per theme: merge entries that share a root cause
- each entry fits a single readable line (about 60 CJK characters); if it
overflows, it is packing multiple themes or detail that belongs in the
linked issue/PR — split it or drop the detail
- line grammar: open with a verb (修复/新增/优化), with the platform
first (Windows/macOS/Linux) when the change is platform-specific;
merge sub-symptoms as 主题:症状、症状; full-width punctuation,
「」 for UI labels, backticks for config keys and commands
- platform entries sit under their platform heading (bold, emoji
prefixed, ordered Windows/macOS/Linux, combined for pairs like
macOS/Linux) at the end of their section;
scripts-workflow/group_platforms.sh regroups, --check verifies
HTML comments are stripped by the update dialog's sanitizer and hidden on
GitHub, so they never reach users. -->
## v(Version Goes Here) ## v(Version Goes Here)
### 🐞 修复问题 <details>
<summary><strong> 🐞 修复问题 </strong></summary>
</details>
<details> <details>
<summary><strong> ✨ 新增功能 </strong></summary> <summary><strong> ✨ 新增功能 </strong></summary>