release-notes

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Release Notes

发布说明

Generates or updates the
[Unreleased]
section of
CHANGELOG.md
from merged PRs since the last release tag.
从上次发布标签以来已合并的PR中生成或更新CHANGELOG.md的
[Unreleased]
章节。

When to Use

使用场景

  • Before a release, to populate the changelog
  • When you want to preview what would go into the next release
  • When asked to update or regenerate the changelog
  • 发布前,用于填充变更日志
  • 想要预览下一版本内容时
  • 需要更新或重新生成变更日志时

Process

流程

Step 1: Detect Last Tag

步骤1:检测最新标签

bash
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
If no tags exist, this is the first release. Use the initial commit as the starting point:
bash
FIRST_COMMIT=$(git rev-list --max-parents=0 HEAD)
bash
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
如果不存在任何标签,则这是首次发布。以初始提交作为起始点:
bash
FIRST_COMMIT=$(git rev-list --max-parents=0 HEAD)

Step 2: Get the Tag Date

步骤2:获取标签日期

bash
TAG_DATE=$(git log -1 --format=%aI "$LAST_TAG" 2>/dev/null || echo "")
bash
TAG_DATE=$(git log -1 --format=%aI "$LAST_TAG" 2>/dev/null || echo "")

Step 3: Gather Merged PRs

步骤3:收集已合并的PR

bash
gh pr list --state merged --base main --search "merged:>$TAG_DATE" --json number,title,labels,mergedAt --jq '.[] | {number, title, labels: [.labels[].name], mergedAt}'
bash
gh pr list --state merged --base main --search "merged:>$TAG_DATE" --json number,title,labels,mergedAt --jq '.[] | {number, title, labels: [.labels[].name], mergedAt}'

Step 4: Classify Each PR

步骤4:对每个PR进行分类

Classify PRs into Keep a Changelog categories based on title prefix and labels:
Title prefixLabelCategory
feat:
,
feature:
feature
,
enhancement
Added
fix:
bug
,
bugfix
Fixed
security:
security
Security
refactor:
,
chore:
,
docs:
,
ci:
,
build:
refactor
,
chore
,
docs
Changed
deprecate:
deprecated
Deprecated
remove:
removed
Removed
If a PR doesn't match any prefix or label, place it in Changed as the default.
Strip the conventional commit prefix from the title when generating the entry. For example:
  • feat: add TUI launcher
    becomes
    Add TUI launcher
  • fix: symlink escape in mounts
    becomes
    Fix symlink escape in mounts
Capitalize the first letter of each entry.
根据标题前缀和标签,将PR归类到《Keep a Changelog》的对应类别中:
标题前缀标签类别
feat:
,
feature:
feature
,
enhancement
新增
fix:
bug
,
bugfix
修复
security:
security
安全
refactor:
,
chore:
,
docs:
,
ci:
,
build:
refactor
,
chore
,
docs
变更
deprecate:
deprecated
废弃
remove:
removed
移除
如果PR不匹配任何前缀或标签,则默认归类到变更类别。
生成条目时,移除约定式提交的前缀。例如:
  • feat: add TUI launcher
    变为
    Add TUI launcher
  • fix: symlink escape in mounts
    变为
    Fix symlink escape in mounts
每个条目首字母大写。

Step 5: Find Ungrouped Commits

步骤5:查找未分组的提交

Find commits since the last tag that are not associated with any merged PR:
bash
git log "$LAST_TAG"..HEAD --oneline --no-merges
For each commit, check if it was part of a PR:
bash
gh pr list --state merged --search "<commit-sha>" --json number --jq '.[0].number'
Commits not associated with a PR go into the Ungrouped commits section.
查找自上次标签以来未关联任何已合并PR的提交:
bash
git log "$LAST_TAG"..HEAD --oneline --no-merges
对每个提交,检查它是否属于某个PR:
bash
gh pr list --state merged --search "<commit-sha>" --json number --jq '.[0].number'
未关联PR的提交将放入未分组提交章节。

Step 6: Format the Changelog Section

步骤6:格式化变更日志章节

Format as Keep a Changelog with PR links:
markdown
undefined
按照《Keep a Changelog》格式进行排版,并添加PR链接:
markdown
undefined

[Unreleased]

[Unreleased]

Added

新增

  • Add TUI launcher for interactive agent selection (#12)
  • Add TUI launcher for interactive agent selection (#12)

Fixed

修复

  • Fix symlink escape in container mounts (#15)
  • Fix symlink escape in container mounts (#15)

Changed

变更

  • Extract testing instructions into TESTING.md (#18)

Only include sections that have entries. Do not include empty sections.

If there are ungrouped commits, add:

```markdown
  • Extract testing instructions into TESTING.md (#18)

仅包含有内容的章节,不要包含空章节。

如果存在未分组提交,添加:

```markdown

Ungrouped commits (not from PRs)

Ungrouped commits (not from PRs)

  • 205875a
    docs: fix resolve_agent_source references
  • efa41b8
    docs: split TODO into individual files
undefined
  • 205875a
    docs: fix resolve_agent_source references
  • efa41b8
    docs: split TODO into individual files
undefined

Step 7: Check for Existing Unreleased Section

步骤7:检查现有未发布章节

Read
CHANGELOG.md
and check if an
[Unreleased]
section already has content.
If it does, ask the user:
"CHANGELOG.md already has entries in the [Unreleased] section. Do you want to: A) Regenerate from scratch (replace existing entries) B) Keep existing entries and add any missing PRs"
读取CHANGELOG.md,检查
[Unreleased]
章节是否已有内容。
如果已有内容,询问用户:
"CHANGELOG.md的[Unreleased]章节已有条目。您希望: A) 重新生成(替换现有条目) B) 保留现有条目并添加遗漏的PR"

Step 8: Write to CHANGELOG.md

步骤8:写入CHANGELOG.md

If
CHANGELOG.md
does not exist, create it with the standard header:
markdown
undefined
如果CHANGELOG.md不存在,创建文件并添加标准头部:
markdown
undefined

Changelog

Changelog

All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
<!-- next-header -->
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
<!-- next-header -->

[Unreleased]

[Unreleased]

[generated entries here]

If `CHANGELOG.md` exists, replace the `## [Unreleased]` section content (everything between `## [Unreleased]` and the next `## [` heading or end of file).
[generated entries here]

如果CHANGELOG.md已存在,替换`## [Unreleased]`章节的内容(即`## [Unreleased]`与下一个`## [`标题或文件结尾之间的所有内容)。

Step 9: Present for Review

步骤9:提交审核

Show the complete
[Unreleased]
section to the user. Allow them to:
  • Request edits ("move PR #42 to Added", "reword this entry", "remove this commit")
  • Approve as-is
Do not proceed until the user approves the changelog content.
向用户展示完整的
[Unreleased]
章节。允许用户:
  • 请求编辑(“将PR #42移至新增类别”、“改写此条目”、“移除此提交”)
  • 直接批准
在用户批准变更日志内容前,请勿继续下一步。

Idempotency

幂等性

This skill is safe to run multiple times:
  • It always checks the current state of
    CHANGELOG.md
    before writing
  • It asks before overwriting existing entries
  • PR data is fetched fresh from GitHub each time
本技能可安全重复运行:
  • 写入前始终检查CHANGELOG.md的当前状态
  • 覆盖现有条目前会询问用户
  • 每次都会从GitHub重新获取PR数据