mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-07 00:39:00 +08:00
Merge pull request #312 from GeWuYou/feat/release-summary-notes
This commit is contained in:
commit
e391833615
95
.github/cliff.toml
vendored
Normal file
95
.github/cliff.toml
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
[remote.github]
|
||||
owner = "GeWuYou"
|
||||
repo = "GFramework"
|
||||
|
||||
[changelog]
|
||||
header = ""
|
||||
|
||||
body = """
|
||||
{%- macro remote_url() -%}
|
||||
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
|
||||
{%- endmacro -%}
|
||||
|
||||
{% macro has_release_highlight(commit) -%}
|
||||
{%- set highlighted = false -%}
|
||||
{%- if commit.remote and commit.remote.pr_labels -%}
|
||||
{%- for label in commit.remote.pr_labels -%}
|
||||
{%- if label == "release-highlight" or label == "highlight" -%}
|
||||
{%- set highlighted = true -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{%- if not highlighted and commit.footers -%}
|
||||
{%- for footer in commit.footers -%}
|
||||
{%- if footer.token == "Release-Highlight" and footer.value | trim == "true" -%}
|
||||
{%- set highlighted = true -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{{ highlighted }}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro print_commit(commit) -%}
|
||||
- {{ commit.message | split(pat="\n") | first | trim | upper_first }}{% if commit.remote and commit.remote.username %} by @{{ commit.remote.username }}{% elif commit.author.name %} by {{ commit.author.name }}{% endif %}{% if commit.remote and commit.remote.pr_number %} in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}){% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% if version -%}
|
||||
## {{ version }} ({{ timestamp | date(format="%Y-%m-%d") }})
|
||||
{% else -%}
|
||||
## 未发布
|
||||
{% endif %}
|
||||
|
||||
{% set highlights = commits | filter(attribute="breaking", value=true) %}
|
||||
{% for commit in commits -%}
|
||||
{% if self::has_release_highlight(commit=commit) == "true" -%}
|
||||
{% set_global highlights = highlights | concat(with=commit) -%}
|
||||
{% endif -%}
|
||||
{% endfor -%}
|
||||
|
||||
{% if highlights | length > 0 -%}
|
||||
## 重点条目
|
||||
{% for commit in highlights -%}
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{% endfor %}
|
||||
|
||||
{% endif -%}
|
||||
|
||||
{% for group, commits in commits | group_by(attribute="group") -%}
|
||||
### {{ group | striptags | trim }}
|
||||
{% for commit in commits -%}
|
||||
{{ self::print_commit(commit=commit) }}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor -%}
|
||||
|
||||
{% if previous and previous.version and version -%}
|
||||
Full Changelog: [{{ previous.version }}...{{ version }}]({{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }})
|
||||
{% endif -%}
|
||||
"""
|
||||
|
||||
footer = ""
|
||||
|
||||
[git]
|
||||
conventional_commits = true
|
||||
filter_unconventional = true
|
||||
split_commits = false
|
||||
protect_breaking_commits = false
|
||||
sort_commits = "oldest"
|
||||
|
||||
commit_parsers = [
|
||||
{ message = ".*\\[skip changelog\\].*", skip = true },
|
||||
{ body = ".*\\[skip changelog\\].*", skip = true },
|
||||
{ message = "^feat", group = "<!-- 0 -->✨ 新功能" },
|
||||
{ message = "^fix", group = "<!-- 1 -->🐛 Bug 修复" },
|
||||
{ message = "^perf", group = "<!-- 2 -->⚡ 优化" },
|
||||
{ message = "^refactor", group = "<!-- 2 -->⚡ 优化" },
|
||||
{ message = "^docs", group = "<!-- 3 -->📝 文档/其他" },
|
||||
{ message = "^test", group = "<!-- 3 -->📝 文档/其他" },
|
||||
{ message = "^chore", group = "<!-- 3 -->📝 文档/其他" },
|
||||
{ message = "^build", group = "<!-- 3 -->📝 文档/其他" },
|
||||
{ message = "^ci", group = "<!-- 3 -->📝 文档/其他" },
|
||||
{ message = "^style", group = "<!-- 3 -->📝 文档/其他" }
|
||||
]
|
||||
|
||||
[git.github]
|
||||
commits = true
|
||||
51
.github/workflows/auto-tag.yml
vendored
51
.github/workflows/auto-tag.yml
vendored
@ -56,13 +56,27 @@ jobs:
|
||||
echo "next_version=${{ steps.semantic_release.outputs.new_release_version }}"
|
||||
echo "next_tag=${{ steps.semantic_release.outputs.new_release_git_tag }}"
|
||||
|
||||
- name: Generate preview release notes
|
||||
if: ${{ steps.semantic_release.outputs.new_release_published == 'true' }}
|
||||
id: cliff_preview
|
||||
uses: orhun/git-cliff-action@v4
|
||||
with:
|
||||
config: .github/cliff.toml
|
||||
args: >-
|
||||
-vv --unreleased --strip header
|
||||
--tag "${{ steps.semantic_release.outputs.new_release_git_tag }}"
|
||||
env:
|
||||
OUTPUT: PREVIEW_RELEASE_NOTES.md
|
||||
GITHUB_REPO: ${{ github.repository }}
|
||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
- name: Write preview summary
|
||||
env:
|
||||
RELEASE_PUBLISHED: ${{ steps.semantic_release.outputs.new_release_published }}
|
||||
RELEASE_NOTES: ${{ steps.semantic_release.outputs.new_release_notes }}
|
||||
CLIFF_RELEASE_NOTES: ${{ steps.cliff_preview.outputs.content }}
|
||||
run: |
|
||||
{
|
||||
echo "## Semantic Release Preview"
|
||||
echo "## Release Preview"
|
||||
echo
|
||||
echo "- Commit: \`${{ github.sha }}\`"
|
||||
echo "- Release needed: \`${{ steps.semantic_release.outputs.new_release_published }}\`"
|
||||
@ -71,13 +85,11 @@ jobs:
|
||||
echo "- Next tag: \`${{ steps.semantic_release.outputs.new_release_git_tag }}\`"
|
||||
echo "- Preview auth: uses \`PAT_TOKEN\` because semantic-release dry-run still performs a remote push permission probe."
|
||||
echo "- Snapshot semantics: this preview is pinned to dispatch SHA \`${{ github.sha }}\`; commits added to \`main\` after the run starts are not included."
|
||||
if [ "${RELEASE_PUBLISHED}" = "true" ] && [ -n "${RELEASE_NOTES}" ]; then
|
||||
if [ "${RELEASE_PUBLISHED}" = "true" ] && [ -n "${CLIFF_RELEASE_NOTES}" ]; then
|
||||
echo
|
||||
echo "<details><summary>Preview release notes</summary>"
|
||||
echo "### 候选发布说明"
|
||||
echo
|
||||
printf '%s\n' "${RELEASE_NOTES}"
|
||||
echo
|
||||
echo "</details>"
|
||||
printf '%s\n' "${CLIFF_RELEASE_NOTES}"
|
||||
fi
|
||||
echo
|
||||
echo "If the version looks correct, approve the \`release-approval\` environment to continue."
|
||||
@ -131,13 +143,26 @@ jobs:
|
||||
echo "next_version=${{ steps.semantic_release.outputs.new_release_version }}"
|
||||
echo "next_tag=${{ steps.semantic_release.outputs.new_release_git_tag }}"
|
||||
|
||||
- name: Generate published release notes
|
||||
if: ${{ steps.semantic_release.outputs.new_release_published == 'true' }}
|
||||
id: cliff_release
|
||||
uses: orhun/git-cliff-action@v4
|
||||
with:
|
||||
config: .github/cliff.toml
|
||||
args: >-
|
||||
-vv --latest --strip header
|
||||
env:
|
||||
OUTPUT: PUBLISHED_RELEASE_NOTES.md
|
||||
GITHUB_REPO: ${{ github.repository }}
|
||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
- name: Write release summary
|
||||
env:
|
||||
RELEASE_PUBLISHED: ${{ steps.semantic_release.outputs.new_release_published }}
|
||||
RELEASE_NOTES: ${{ steps.semantic_release.outputs.new_release_notes }}
|
||||
CLIFF_RELEASE_NOTES: ${{ steps.cliff_release.outputs.content }}
|
||||
run: |
|
||||
{
|
||||
echo "## Semantic Release Publish"
|
||||
echo "## Release Publish"
|
||||
echo
|
||||
echo "- Commit: \`${{ github.sha }}\`"
|
||||
echo "- Preview last tag: \`${{ needs.preview.outputs.last_tag }}\`"
|
||||
@ -148,12 +173,10 @@ jobs:
|
||||
echo "- Next version: \`${{ steps.semantic_release.outputs.new_release_version }}\`"
|
||||
echo "- Next tag: \`${{ steps.semantic_release.outputs.new_release_git_tag }}\`"
|
||||
echo "- Snapshot semantics: this publish run still uses dispatch SHA \`${{ github.sha }}\`; commits added to \`main\` after the preview started are excluded."
|
||||
if [ "${RELEASE_PUBLISHED}" = "true" ] && [ -n "${RELEASE_NOTES}" ]; then
|
||||
if [ "${RELEASE_PUBLISHED}" = "true" ] && [ -n "${CLIFF_RELEASE_NOTES}" ]; then
|
||||
echo
|
||||
echo "<details><summary>Published release notes</summary>"
|
||||
echo "### 已发布说明"
|
||||
echo
|
||||
printf '%s\n' "${RELEASE_NOTES}"
|
||||
echo
|
||||
echo "</details>"
|
||||
printf '%s\n' "${CLIFF_RELEASE_NOTES}"
|
||||
fi
|
||||
} >> "${GITHUB_STEP_SUMMARY}"
|
||||
|
||||
36
.github/workflows/publish.yml
vendored
36
.github/workflows/publish.yml
vendored
@ -242,25 +242,53 @@ jobs:
|
||||
packages: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository (at tag)
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
|
||||
- name: Download package artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: packages
|
||||
path: ./packages
|
||||
|
||||
- name: Generate release notes
|
||||
id: cliff_release
|
||||
uses: orhun/git-cliff-action@v4
|
||||
with:
|
||||
config: .github/cliff.toml
|
||||
args: >-
|
||||
-vv --latest --strip header
|
||||
env:
|
||||
OUTPUT: RELEASE_NOTES.md
|
||||
GITHUB_REPO: ${{ github.repository }}
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
# 无论某一侧包源发布是否失败,都继续创建 Release。
|
||||
# 合规工件由独立 workflow 生成,当前发布流不再假设这些文件在同一次运行中可用。
|
||||
- name: Create GitHub Release and Upload Assets
|
||||
uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
generate_release_notes: true
|
||||
name: "Release ${{ github.ref_name }}"
|
||||
body: |
|
||||
Release created by CI for tag ${{ github.ref_name }}
|
||||
Package version: ${{ needs.build-pack.outputs.package_version }}
|
||||
body_path: RELEASE_NOTES.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
files: |
|
||||
./packages/*.nupkg
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- name: Write publish summary
|
||||
env:
|
||||
CLIFF_RELEASE_NOTES: ${{ steps.cliff_release.outputs.content }}
|
||||
run: |
|
||||
{
|
||||
echo "## GitHub Release"
|
||||
echo
|
||||
echo "- Tag: \`${{ github.ref_name }}\`"
|
||||
echo "- Package version: \`${{ needs.build-pack.outputs.package_version }}\`"
|
||||
echo
|
||||
printf '%s\n' "${CLIFF_RELEASE_NOTES}"
|
||||
} >> "${GITHUB_STEP_SUMMARY}"
|
||||
|
||||
@ -16,9 +16,9 @@
|
||||
- 恢复点编号:`SEMREL-RP-004`
|
||||
- 当前阶段:`Phase 2`
|
||||
- 当前焦点:
|
||||
- 将 preview / release 的 PAT 校验收敛为同一个复用入口,避免后续修复在两段脚本间漂移
|
||||
- 在 PAT 校验阶段提前识别“仅有 read、没有 push”的 token,真正覆盖 `git push --dry-run` 的权限前提
|
||||
- 将 active tracking 中已稳定的历史完成项归档,恢复默认入口的可读性
|
||||
- 收敛 PR #312 最新 AI review 的 release notes 输出问题
|
||||
- 确保 `.github/cliff.toml` 不再重复输出同一批 commits
|
||||
- 确保 `publish.yml` 创建 GitHub Release 时通过文件传递多行 release notes
|
||||
|
||||
### 已知风险
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
- `cycjimmy/semantic-release-action@v6` 需要在 preview / release 两端都安装 `conventional-changelog-conventionalcommits`
|
||||
以保证 `conventionalcommits` preset 在 GitHub Actions 中可解析
|
||||
- 当前仓库本地 `dotnet clean/build` 会带出既有 analyzer warnings;本轮仅修正发版配置与文档,不额外处理这些历史 warning
|
||||
- `git-cliff-action` 的 `OUTPUT` 文件需要在 `softprops/action-gh-release` 执行时保留在当前工作目录,后续如调整
|
||||
working-directory 或 artifact 路径,需要同步复查 `body_path`
|
||||
|
||||
## 已完成
|
||||
|
||||
@ -39,17 +41,32 @@
|
||||
`semantic-release` 的 `git push --dry-run` 阶段才失败
|
||||
- 已为 PAT 校验的 `mktemp` 文件补充 `trap` 清理,避免异常退出时遗留临时文件路径干扰日志
|
||||
- 已同步更新 active trace 到 `SEMREL-RP-004`,记录本轮 PR review 收敛结果
|
||||
- 已用 `$gframework-pr-review` 抓取 PR #312 最新 review payload,确认未失败测试、未发现 MegaLinter 明细,仍有
|
||||
CodeRabbit / Greptile 针对 release notes 的未解决线程
|
||||
- 已移除 `.github/cliff.toml` 中 `## What's Changed` 下的未分组 commit 循环,仅保留按 Conventional Commit group
|
||||
分类后的输出,避免每个 commit 在生成的 changelog 中出现两次
|
||||
- 已将 `.github/workflows/publish.yml` 的 GitHub Release 正文从多行 expression 改为 `body_path: RELEASE_NOTES.md`,
|
||||
复用 `git-cliff-action` 写出的 release notes 文件
|
||||
|
||||
## 验证
|
||||
|
||||
- `python3 -c 'import tomllib; tomllib.load(open(".github/cliff.toml", "rb")); print("cliff.toml OK")'`
|
||||
- 结果:通过
|
||||
- 备注:确认 `.github/cliff.toml` 仍为合法 TOML
|
||||
- `python3 -c 'import yaml; yaml.safe_load(open(".github/workflows/publish.yml", encoding="utf-8")); print("publish.yml OK")'`
|
||||
- 结果:通过
|
||||
- 备注:确认 `.github/workflows/publish.yml` 仍可解析为 YAML
|
||||
- `yq '.jobs."create-release".steps[] | select(.name == "Create GitHub Release and Upload Assets") | .with' .github/workflows/publish.yml`
|
||||
- 结果:通过
|
||||
- 备注:确认 release step 现在使用 `body_path: RELEASE_NOTES.md`
|
||||
- `dotnet build GFramework.sln -c Release`
|
||||
- 结果:通过
|
||||
- 备注:Release 构建通过,`639 warning / 0 error`;warning 为仓库既有基线,preview 鉴权修复后与本轮 PAT 校验收敛后复验结果一致
|
||||
- 备注:Release 构建通过,`0 warning / 0 error`;本轮只改动 GitHub Actions / git-cliff 配置
|
||||
- 更早阶段的 dry-run / tag /抽象项目验证已归档到
|
||||
`ai-plan/public/semantic-release-versioning/archive/todos/semantic-release-versioning-2026-04-26.md`
|
||||
|
||||
## 下一步
|
||||
|
||||
1. 手动重跑 `Semantic Release Version and Tag` 的 preview job,确认 read-only PAT 会在校验步骤提前失败、可写 PAT 不再进入 `git push --dry-run ... 403`
|
||||
2. 推送本轮修复后重新抓取 PR review,确认 CodeRabbit / Greptile 的 open threads 已转为过时或可关闭
|
||||
3. 如 CI 仍报告权限边界问题,再决定是否将 PAT 校验升级为更贴近真实链路的远端 git 探测
|
||||
1. 提交并推送本轮 PR review 修复
|
||||
2. 重新抓取 PR review,确认 CodeRabbit / Greptile 的 release notes open threads 已转为过时或可关闭
|
||||
3. 如 CI 仍报告 release notes 发布问题,再优先复查 `git-cliff-action` 输出文件路径与 `action-gh-release` 输入契约
|
||||
|
||||
@ -1,5 +1,30 @@
|
||||
# Semantic Release 版本迁移追踪
|
||||
|
||||
## 2026-05-01
|
||||
|
||||
### 当前恢复点(SEMREL-RP-004)
|
||||
|
||||
- 通过 `$gframework-pr-review` 抓取当前分支 PR #312:
|
||||
- CodeRabbit 对 `.github/cliff.toml` 提出 1 个未解决线程,指出 release notes 会重复输出 commit
|
||||
- Greptile 对 `.github/cliff.toml` 提出同一问题的未解决线程
|
||||
- Greptile 对 `.github/workflows/publish.yml` 提出 1 个未解决线程,指出多行 release notes expression 作为
|
||||
`body` 传入 GitHub Release action 风险较高
|
||||
- CTRF 测试报告显示 `2247 passed / 0 failed`
|
||||
- 未找到 MegaLinter 明细块
|
||||
- 本地复核结论:
|
||||
- `.github/cliff.toml` 先遍历 `commits` 输出平铺列表,再对同一批 `commits` 按 `group` 输出,重复问题成立
|
||||
- `.github/workflows/publish.yml` 已让 `git-cliff-action` 写出 `RELEASE_NOTES.md`,因此 `action-gh-release` 可直接使用
|
||||
`body_path`
|
||||
- 已应用修复:
|
||||
- 删除 `.github/cliff.toml` 中 `## What's Changed` 下的未分组循环,只保留 grouped 输出
|
||||
- 将 `.github/workflows/publish.yml` 的 `body` 改为 `body_path: RELEASE_NOTES.md`
|
||||
- 已完成语法检查:
|
||||
- `.github/cliff.toml` 通过 Python `tomllib` 解析
|
||||
- `.github/workflows/publish.yml` 通过 PyYAML 解析
|
||||
- `yq` 确认 release step 使用 `body_path`
|
||||
- `dotnet build GFramework.sln -c Release` 通过,`0 warning / 0 error`。
|
||||
- 下一步是提交并推送本轮 PR review 修复,然后重新抓取 PR review 确认相关线程状态。
|
||||
|
||||
## 2026-04-26
|
||||
|
||||
### 当前恢复点(SEMREL-RP-004)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user