Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

9 watching

Forks

Repository files navigation

tdesign-changelog-action

tdesign-changelog-action 是用于 monorepo 和单仓发布流程的 GitHub Action。它从 PR 描述中收集 Changelog,在 release PR 中生成发布日志,并在 release PR 合并后发布 Node 包或创建 GitHub Release/tag。

tdesign-changelog-action 支持包含 package.json 的 Node 包和包含 pubspec.yaml 的 Flutter 包。版本更新、release/* 分支及 release PR 需要由 Changesets、自有脚本或其他发布工具创建,tdesign-changelog-action 不负责修改包版本或创建 release PR。

功能概览

  • 从普通 PR 描述中提取结构化更新日志。
  • 通过 /changelog 指令、Review 通过或编辑确认评论提交日志。
  • 按包生成 .changelog/pr-<PR number>.md 暂存文件,并补充贡献者和 PR 链接。
  • 在 release PR 中按类型和 scope 汇总日志,生成中英文 Changelog 确认评论。
  • release PR 合并后发布 Node 包,并按仓库模式创建 ${name}@${version} 或纯版本号 tag。
  • 识别同一仓库中的 Node 和 Flutter 包。

接入示例

以下配置将 Changelog、Review 回调和 release 发布拆分为三个 workflow。

auto-changelog.yml

Review 通过时上传 PR 编号;release PR 打开或 PR 评论发生变化时,直接运行 tdesign-changelog-action。

name: auto-changelog

on:
  pull_request:
    types: [opened]
  pull_request_review:
    types: [submitted]
  issue_comment:
    types: [created, edited]

jobs:
  changelog:
    if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved'
    runs-on: ubuntu-latest
    steps:
      - run: echo "${{ github.event.pull_request.number }}" > pr-id.txt

      - uses: actions/upload-artifact@v4
        with:
          name: pr-id
          path: pr-id.txt
          retention-days: 5

  comment-release-changelog:
    if: github.event_name == 'pull_request' && startsWith(github.head_ref, 'release/')
    runs-on: ubuntu-latest
    steps:
      - name: auto-changelog
        uses: TDesignOteam/tdesign-changelog-action@develop
        with:
          token: ${{ secrets.TDESIGN_BOT_TOKEN }}
          packages: 'tdesign-miniprogram,@tdesign/uniapp,@tdesign/uniapp-chat'

  commit-changelog:
    if: github.event_name == 'issue_comment' && github.event.issue.pull_request
    runs-on: ubuntu-latest
    steps:
      - name: auto-changelog
        uses: TDesignOteam/tdesign-changelog-action@develop
        with:
          token: ${{ secrets.TDESIGN_BOT_TOKEN }}
          packages: 'tdesign-miniprogram,@tdesign/uniapp,@tdesign/uniapp-chat'

auto-changelog-callback.yml

Review workflow 成功后下载 PR 编号,并在可信的 workflow_run 上下文中提交 Changelog。

name: auto-changelog-callback

on:
  workflow_run:
    workflows:
      - auto-changelog
    types:
      - completed

jobs:
  commit-changelog:
    if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request_review' }}
    runs-on: ubuntu-latest
    steps:
      - name: Download pr id
        uses: dawidd6/action-download-artifact@v8
        with:
          workflow: ${{ github.event.workflow_run.workflow_id }}
          run_id: ${{ github.event.workflow_run.id }}
          name: pr-id

      - name: Output pr id
        id: pr
        run: echo "id=$(cat pr-id.txt)" >> "$GITHUB_OUTPUT"

      - name: auto-changelog
        uses: TDesignOteam/tdesign-changelog-action@develop
        with:
          token: ${{ secrets.TDESIGN_BOT_TOKEN }}
          packages: 'tdesign-miniprogram,@tdesign/uniapp,@tdesign/uniapp-chat'
          pr_number: ${{ steps.pr.outputs.id }}

auto-release.yml

release PR 合并后完成项目构建,并通过 OIDC 发布。pnpm install 和构建命令可按项目调整。

name: auto-release

on:
  pull_request:
    types: [closed]

permissions:
  contents: read
  id-token: write

jobs:
  publish:
    if: github.event.pull_request.merged && startsWith(github.head_ref, 'release/')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v6
        with:
          node-version-file: .node-version

      - run: pnpm install

      - run: pnpm build

      - run: pnpm run uniapp build:npm

      - uses: actions/setup-node@v6
        with:
          node-version: 24

      - uses: TDesignOteam/tdesign-changelog-action@develop
        with:
          token: ${{ secrets.TDESIGN_BOT_TOKEN }}
          packages: 'tdesign-miniprogram,@tdesign/uniapp,@tdesign/uniapp-chat'

TDESIGN_BOT_TOKEN 用于读取 PR、提交日志和创建 GitHub Release/tag。发布 workflow 必须使用 pull_request: closed;不要改为 pull_request_target,否则后续 OIDC 发布会被拒绝。

Action 参数

参数 是否必需 说明
token 按流程 GitHub API、Git clone/push 和创建 Release 使用的 token。仅生成普通 PR 的 changelog output 时可为空,完整流程需要有效 token。
packages monorepo Changelog 流程必需 参与日志提取的包名。支持逗号或多行输入,名称必须与 manifest 中的 name 完全一致。release 检测未配置时会使用发现的全部包;single 模式无需配置。
pr_number workflow_run 必需 workflow_run 无法从事件直接获得 PR 编号时使用,其他事件不需要。
translate-secret-id 否 腾讯混元翻译 SecretId;与 translate-secret-key 同时配置后生成英文 release 日志评论。
translate-secret-key 否 腾讯混元翻译 SecretKey。
mode 否 仓库模式:single(单仓) 或 monorepo(monorepo)。默认 monorepo。single 模式下不依赖 .changelog/*.md 暂存文件,直接从 tag 区间已合并 PR 的 body 生成发布日志,且使用纯版本号 git tag(如 1.2.3)。
package-json-path 否 single 模式下指定 package.json 的相对路径,默认读取仓库根目录的 package.json。仅 single 模式生效。
changelog-path 否 single 模式下指定 CHANGELOG.md 的相对路径,默认在包目录下读写 CHANGELOG.md / CHANGELOG.en-US.md。仅 single 模式生效。
from-tag 否 覆盖日志区间起始 tag。单仓预发布默认取目标 ref 可达的最近 tag,稳定版默认取最近稳定 tag;目标历史无 tag 时扫描全部历史。
to-tag 否 覆盖日志区间结束 ref。默认取 release PR 的 base 分支。
Output 说明
changelog 普通 PR 打开且提取到日志时输出待确认的评论正文。tdesign-changelog-action 不会自动发布该评论,如需使用该模式,应由后续步骤消费 output 并创建评论。

更新日志格式

tdesign-changelog-action 从 PR 描述中的 ### 📝 更新日志 区块提取日志。包名使用四级标题,日志项使用以下格式:

type(scope): message
  • type:日志类型,使用小写;支持 feat、fix、docs/doc、perf/refactor、breaking/break,其他类型归入 Others。
  • scope:可选,表示组件或功能名称,生成日志时会转换为 PascalCase。
  • message:必填,从用户视角描述本次变更。
  • 包名区分大小写,必须与 package.json 或 pubspec.yaml 中的 name 一致。
  • 使用 all 可将日志应用到 packages 参数列出的所有包。

日志提取阶段不会校验条目格式;不符合 type(scope): message 的条目可能被暂存,但在生成 release 日志时会被忽略。

示例:

### 📝 更新日志

#### all

- docs: 更新公共使用说明

#### pkg-a

- feat(Button): 新增加载状态
- feat(Button): 新增图标插槽
- fix(use-popup): 修复弹层关闭异常
- breaking: 移除废弃属性

跳过日志

满足以下任一条件时,不会为 PR 写入暂存日志;如果同一 PR 已存在暂存文件,对应文件会被删除:

  • PR 作者类型为 Bot。
  • PR 带有 skip-changelog 标签。
  • PR 分支以 release/ 开头。
  • PR 描述中勾选 [x] 本条 PR 不需要纳入 Changelog。

普通 PR 打开时仍可能先生成 changelog output,跳过条件在确认并写入暂存文件时生效。

确认与暂存

普通 PR 打开后,tdesign-changelog-action 通过 changelog output 提供一条带提示行的待确认评论。可以通过以下任一方式确认日志:

  1. 编辑待确认评论,检查日志内容并删除第一行提示,使评论以 ### 📝 更新日志 开头。
  2. 由白名单成员在 PR 下创建内容为 /changelog 的评论。指令允许首尾空白,但不能包含其他内容;PR 已合并时会从目标分支创建补日志 PR。
  3. 由白名单成员提交状态为 approved 的 PR Review。

通过 /changelog 或 Review 确认时,tdesign-changelog-action 从最新 PR 描述提取日志;编辑待确认评论时,以修改后的评论内容为准。随后 tdesign-changelog-action 向 PR 分支提交:

<package-dir>/.changelog/pr-<PR number>.md

暂存文件包含 PR 编号、贡献者、日志内容和 PR 链接,提交信息为 chore: stash changelog [ci skip]。重复确认同一 PR 会更新对应文件,不会创建多份日志。

如果原 PR 已合并,tdesign-changelog-action 不再向原 head 分支推送,而是从原 PR 的 base 分支创建 changelog/pr-<PR number> 分支并提交补日志 PR。重复执行 /changelog 时,如果该补日志 PR 仍处于打开状态,则更新现有分支,不会重复创建 PR。该流程要求 token 具有 Contents 写权限和 Pull requests 写权限。

/changelog 指令限制

  • 只响应 PR 评论,不响应普通 Issue 评论。
  • 只响应 created 事件,不会因编辑已有评论为 /changelog 而触发。
  • 不处理 release/* PR。
  • 评论者必须在维护者白名单中。

当前白名单固定读取 Tencent/tdesign 的 .pr-comment-ci-whitelist,尚不支持通过 Action 参数或仓库文件配置。Review approved 和编辑确认评论同样受该白名单限制。

编辑确认根据评论正文前缀识别,不校验评论是否由 tdesign-changelog-action 创建。以 ### 📝 更新日志、# 🎉 发布 或 # 🎉 Release 开头的任意已编辑 PR 评论都可能触发对应流程,因此白名单应只包含可信维护者。

转换后的日志

release PR 打开时,tdesign-changelog-action 读取各包的 .changelog/*.md,按类型分组;相同 scope 下存在多条日志时会生成二级列表。上面的 pkg-a 日志将转换为:

### 🚨 Breaking Changes

- 移除废弃属性 @contributor ([#123](https://github.com/owner/repo/pull/123))

### 🚀 Features

- `Button`:
  - 新增加载状态 @contributor ([#123](https://github.com/owner/repo/pull/123))
  - 新增图标插槽 @contributor ([#123](https://github.com/owner/repo/pull/123))

### 🐞 Bug Fixes

- `UsePopup`: 修复弹层关闭异常 @contributor ([#123](https://github.com/owner/repo/pull/123))

### 📝 Documentation

- 更新公共使用说明 @contributor ([#123](https://github.com/owner/repo/pull/123))

类型与最终分组的对应关系:

输入类型 最终分组
breaking、break 🚨 Breaking Changes
feat 🚀 Features
fix 🐞 Bug Fixes
perf、refactor 📈 Performance
docs、doc 📝 Documentation
其他类型 🚧 Others

基于 tag 的发布日志(单仓)

单仓场景下,各 PR 的更新日志直接写在 PR 描述的 ### 📝 更新日志 下(扁平列表,无 #### package 分段):

### 📝 更新日志

- fix(aa): aa

设置 mode: single 后,release PR 打开时 tdesign-changelog-action 会:

  1. 通过 GitHub API 读取 manifest 和 tag,无需 clone/checkout 仓库。预发布版本取目标 ref 可达的最近 tag,稳定版取最近的非 alpha/beta tag;from-tag 可覆盖起点,目标历史无 tag 时扫描全部历史。release PR 的 base 分支(或 to-tag)作为终点。
  2. 分页获取区间内全部 commit,并关联出对应的已合并 PR 编号(去重),兼容 merge、squash 和 rebase 合并。
  3. 逐个拉取 PR body,复用与普通 PR 相同的跳过规则(Bot / skip-changelog 标签 / release 分支 / 手动勾选),从 ### 📝 更新日志 抓取日志。
  4. 拼接贡献者与 PR 链接,按类型分组渲染,生成与暂存模式完全一致的 # 🎉 发布 / # 🎉 Release 确认评论;下游确认与 Release 创建流程不变。

PR body 没有有效的 type(scope): message 日志且未显式跳过时,tdesign-changelog-action 会使用 PR 标题作为回退。符合该格式的标题会保留类型与 scope;其他标题自动归入 Others。模板中未勾选的“不需要纳入 Changelog”选项不视为有效日志。

单仓模式下,release PR 合并后的 GitHub tag 使用纯版本号(如 1.2.3)而非 ${name}@${version}。预发布版本会创建 GitHub prerelease,并生成相对最近 tag 的增量日志;稳定版会汇总最近稳定 tag 之后的完整日志。

可通过 package-json-path 指定非根目录的 package.json,通过 changelog-path 指定自定义的 CHANGELOG.md 读写位置。

所有触发 tdesign-changelog-action 的 workflow(release PR 打开、确认评论、release PR 关闭)必须传入相同的单仓配置,例如:

- uses: TDesignOteam/tdesign-changelog-action@develop
  with:
    token: ${{ secrets.TDESIGN_BOT_TOKEN }}
    mode: single
    package-json-path: package.json
    changelog-path: CHANGELOG.md

扫描单个 commit 或 PR 失败时会产生 GitHub Actions warning 并继续,因此应检查 warning 以确认日志是否完整。仓库没有任何 tag 时会分页扫描目标分支的全部提交,历史较长的仓库可通过 from-tag 限定首次纳入日志的范围。

Release 流程

1. 创建 release PR

外部发布工具需要完成以下工作:

  • 创建以 release/ 开头的分支和 PR。
  • 从当前仓库创建 release PR,不使用 fork 分支。
  • 修改待发布包 manifest 中已有的 version。
  • 确保版本 manifest 在 PR 中属于 modified 文件,而不是新增文件。

tdesign-changelog-action 根据 GitHub API 返回的 package.json 或 pubspec.yaml patch 识别待发布包和版本。预发布版本使用首个 prerelease 标识符作为 dist-tag,例如 alpha、beta 或 rc;稳定版本使用 latest。大型 diff 导致 GitHub 不返回 manifest patch 时,tdesign-changelog-action 会终止发布。

2. 确认 release 日志

release PR 打开后,tdesign-changelog-action 为 monorepo 的 latest 版本以及单仓的所有版本生成以 # 🎉 发布 开头的中文确认评论。配置两个翻译参数后,还会生成以 # 🎉 Release 开头的英文评论。

检查评论内容并删除第一行提示后,tdesign-changelog-action 会:

  • 删除该包的 .changelog/*.md 暂存文件。
  • 将中文内容写入 CHANGELOG.md,英文内容写入 CHANGELOG.en-US.md。
  • 将变更提交并推送到 release 分支。

中英文是两条独立评论,需要分别确认。

3. 合并并发布

release PR 合并后,monorepo 各类包的处理方式如下:

包类型 Registry 发布 GitHub Release/tag
公共 Node 包 monorepo 执行 pnpm publish --no-git-checks --filter <name> --tag <tag>;单仓执行 npm publish <package-dir> --tag <tag> 仅 latest 且存在非空 Changelog 时尝试创建
private: true 的 Node 包 跳过 仅 latest 且存在非空 Changelog 时尝试创建
公共 Flutter 包 tdesign-changelog-action 不执行 flutter pub publish 所有版本均尝试创建
publish_to: none 的 Flutter 包 跳过 所有版本均尝试创建

GitHub Release 标题和 tag 均为 ${name}@${version}。Flutter 包可使用该 tag 触发独立的 OIDC 发布工作流。

single 模式下,所有版本均尝试创建纯版本号 GitHub Release/tag;预发布版本标记为 prerelease。Node registry 发布和私有包跳过规则保持不变。Release/tag 创建失败会使 workflow 失败,以避免后续版本缺少日志起始 tag。

Node monorepo 发布使用 pnpm 的 --filter,因此必须配置 pnpm workspace,并在运行 tdesign-changelog-action 前安装 pnpm。单仓 Node 发布使用 npm;仅包含 Flutter 包时不需要 pnpm。

Registry 发布或 GitHub Release/tag 创建失败都会使 workflow 失败。重跑时会跳过已经发布的包版本和已经存在的 GitHub Release/tag,并继续补齐未完成步骤。

release PR 合并发布必须使用 pull_request: closed。tdesign-changelog-action 不支持 pull_request_target,避免由该事件创建的 Release/tag 导致后续 OIDC 发布被拒绝。

包发现规则

tdesign-changelog-action 会递归查找 package.json 和 pubspec.yaml,包发现本身不依赖 pnpm-workspace.yaml:

  • 如果发现嵌套包,则忽略仓库根目录的 manifest;没有嵌套包时,根 manifest 作为单包处理。
  • 忽略 .git、node_modules、dist、build、coverage、example、examples、.dart_tool 和 .pub-cache 等目录。
  • 不跟随符号链接。
  • 同一目录不能同时包含 package.json 和 pubspec.yaml。
  • manifest 必须包含非空字符串 name。
  • packages 参数按包名精确过滤。未知包名可能出现在普通 PR 的预览评论中,但确认时不会写入暂存文件,因此应在接入时校验包名。

当前不需要 .tdesign-changelog.json,tdesign-changelog-action 也不会读取该文件。

支持的事件

事件 条件 行为
pull_request: opened 普通 PR 生成 changelog output
pull_request: opened 非 fork 的 release/* PR 生成 release Changelog 确认评论
pull_request: closed 已合并的 release/* PR 发布 Node 包并创建符合条件的 GitHub Release/tag
pull_request_review: submitted approved、白名单成员、普通 PR 从 PR 描述确认并暂存日志
issue_comment: created PR 评论为 /changelog、白名单成员 从 PR 描述确认并暂存日志;原 PR 已合并时创建补日志 PR
issue_comment: edited 白名单成员 确认普通 PR 或 release Changelog 评论
workflow_run: completed 来源为成功的 pull_request_review workflow 使用 pr_number 确认日志的兼容入口

workflow_run 路径依赖调用流程提供 pr_number 和工作区中的 pr-id.txt。接入示例通过 artifact 在两个 workflow 之间传递这两项信息。

开发

项目使用 pnpm:

pnpm install
pnpm test
pnpm lint
pnpm typecheck
pnpm build

修改 src 后需要执行 pnpm build 更新 dist/index.mjs,GitHub Action 实际运行该构建产物。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages