Files
在7楼 9e79ca09a1 维护[#1153]: 发布策略重构——CI 托管版本号与单主干 alpha/stable 通道 (#1160)
* chore: 补齐 agent 配置文档,版本升至 4.0.8 (#1152)

* docs(agents): 术语表迁到根目录 CONTEXT.md,补齐 agent 配置文档

新增 AGENTS.md 指向 issue tracker / triage 标签 / 领域文档三份说明,
docs/glossary.md 的内容改为 CONTEXT.md 的术语条目后删除。

* chore: VersionPrefix 升到 4.0.8

* docs(changelog): 开 4.0.8 段落

与 common.props 的 VersionPrefix 同号,否则 CI 的版本一致性校验会失败。

* docs: 版本与分支策略重构的 ADR-0002 与术语表(#1153)

* feat: CI 托管版本号的算号与 notes 生成脚本(#1154 #1155)

- version-next.sh:alpha/stable/latest 算号,权威源为 git tag 历史
- release-notes.sh:PR 标题分类生成 release notes 与 CHANGELOG 段落,不合规标题兜底
- 两个 fixture 测试套件(临时 git 仓库 / 模拟标题列表),并作为 ScriptTests job 纳入 PR CI

* refactor: code-review 修复——断言框架提取 test-lib、section 对齐 CHANGELOG 无空行风格、latest 复用 version-next.sh、补跨 major fixture 与错误信息断言

* feat: alpha 通道——main 合并自动推 alpha 镜像(#1156)

- 新增 alpha.yml:version-next.sh 算号,推 :x.y.z-alpha.N + :alpha 到 DockerHub/GHCR,串行防撞号
- Dockerfile:ARG VERSION 完整版本显式注入(构建时烘焙),补 OCI version LABEL;VERSION_SUFFIX 暂时兼容
- ci.yml ScriptTests:真实 tag 历史上的 alpha dry-run 冒烟

* feat: 稳定版通道——手动触发,全套制品 + CHANGELOG 回写(#1157)

- workflow_dispatch 下拉 patch/minor/major,version-next.sh 算号
- release-notes.sh 生成 notes(无合并 PR 时发版失败,不发空版本)
- softprops/action-gh-release 建 tag 与 Release(重跑幂等)
- 镜像 :x.y.z + :latest,显式 VERSION 注入
- CHANGELOG 段落 bot 回写 main([skip ci] 防触发 alpha)

* refactor: 拆除旧发布体系,版本权威源切换为 git tag 历史(#1158)

- common.props:VersionPrefix 0.0.0 + VersionSuffix dev,仅本地兜底(已验证宿主产物为 0.0.0-dev)
- ci.yml:删版本一致性校验与播报步骤,PR 目标收窄为 main
- 删除 preview-image/release/verify-pr-target 三个旧 workflow 与 version.sh/report-version.sh
- publish.sh:版本与 notes 改用新脚本
- codeql/dependabot/README 的 develop 引用改为 main

* fix: code-review 修复——Console zip 显式注入程序集版本、changelog 逻辑入脚本、platforms 断链修復

- publish.sh:dotnet publish 补 -p:Version,否则 zip 内程序集恒为 0.0.0-dev(Spec 轴关键发现);本地兜底统一为 0.0.0-dev
- Dockerfile:删除已无调用方的 VERSION_SUFFIX 遗留分支
- 提取 update-changelog.sh(重跑安全:同版本段落替换而非重复插入)+ 5 个 fixture,纳入 ScriptTests
- 术语对齐 CONTEXT.md:避免词「预览镜像」改为「alpha 版本镜像」
- platforms:青龙 QL_BRANCH 默认改 main,baihu/daidai/qinglong 脚本内 blob/develop 链接改 main,两份 README 的先行版说明对齐单主干
2026-09-28 01:24:53 +08:00

109 lines
3.2 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 新发布策略(ADR-0002)的 release notes / CHANGELOG 段落生成器。
# 输入是自上个稳定 tag 以来合并的 PR 标题(squash 提交的标题行),
# 按类型前缀分类排序输出;PR 标题不做强制校验,不合规的原样收录进末尾,绝不中断发版。
#
# notes [--since <tag>] [--from-file <f>] -> "- <标题>" 条目列表
# section <版本> [--since <tag>] [--from-file <f>] -> "## <版本>" + 空行 + 条目
#
# 默认 --since 为最新稳定 tag(version-next.sh latest);--from-file 是测试 seam。
set -euo pipefail
repo_dir=${VERSION_REPO_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}
die() {
echo "$1" >&2
exit 1
}
# 分类优先级:BREAKING > Feature > Fix > 维护 > 其他。
# 判定前剥掉前导 **(历史 BREAKING 条目用粗体包裹),但输出保留原文。
rank_of() {
local t=$1
t=$(sed -E 's/^\*+//; s/^[[:space:]]+//' <<< "$t")
case "$t" in
BREAKING* | breaking*) echo 0 ;;
Feature* | feature* | feat*) echo 1 ;;
Fix* | fix*) echo 2 ;;
维护*) echo 3 ;;
*) echo 4 ;;
esac
}
# 稳定排序:按 rank 分类,同类内保持输入(合并)顺序
sort_titles() {
local i=0 t
while IFS= read -r t; do
[ -n "$t" ] || continue
echo "$(rank_of "$t") $i $t"
i=$((i + 1))
done | sort -s -n -k1,1 -k2,2 | cut -d' ' -f3-
}
read_titles() { # <since> <from_file>
if [ -n "$2" ]; then
cat "$2"
elif [ -n "$1" ]; then
git -C "$repo_dir" log --pretty=%s "$1..HEAD"
else
git -C "$repo_dir" log --pretty=%s
fi
}
latest_stable() {
bash "$repo_dir/scripts/version-next.sh" latest
}
entries() { # <since> <from_file>:条目列表;空列表报错
local since=$1 from_file=$2 titles
titles=$(read_titles "$since" "$from_file")
[ -n "${titles// /}" ] || die "自 ${since:-仓库起点} 以来没有合并的 PR,拒绝发空版本"
sort_titles <<< "$titles" | sed 's/^/- /'
}
cmd=${1:-help}
shift || true
case "$cmd" in
notes | section)
version=""
if [ "$cmd" = section ]; then
version=${1:-}
[ -n "$version" ] || die "section 需要版本号参数"
shift
fi
since=""
from_file=""
while [ $# -gt 0 ]; do
case "$1" in
--since)
since=$2
shift 2
;;
--from-file)
from_file=$2
shift 2
;;
*) die "未知参数: $1" ;;
esac
done
[ -n "$from_file" ] || since=${since:-$(latest_stable)}
body=$(entries "$since" "$from_file")
if [ "$cmd" = section ]; then
# 与仓库现有 CHANGELOG 风格一致:二级标题后直接跟条目,不空行
printf '## %s\n%s\n' "$version" "$body"
else
echo "$body"
fi
;;
*)
cat <<EOF
用法:$0 {notes|section <版本>} [--since <tag>] [--from-file <文件>]
notes 输出分类排序后的 "- <标题>" 条目
section 输出 CHANGELOG 段落(## <版本> + 条目)
--since 从该 tag 到 HEAD 的提交标题(缺省:最新稳定 tag)
--from-file 从文件读标题列表(测试 seam,优先级高于 --since)
环境变量 VERSION_REPO_DIR 可指定目标 git 仓库。
EOF
;;
esac