Skip to content

Conversation

@yuanyuanxin
Copy link
Contributor

@yuanyuanxin yuanyuanxin commented Jan 27, 2026

Summary

  • 添加可复用的 Composite Action,用于解析 CHANGELOG.md 并自动创建 GitHub Release
  • 集中管理 release 逻辑,简化各业务仓库的 workflow 配置

文件变更

  • actions/auto-release/action.yml - Composite Action 定义
  • actions/auto-release/README.md - 使用说明文档

使用方式

业务仓库只需 3 行引用:

- uses: wuji-technology/.github/actions/auto-release@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}

Test plan

  • 合并后创建 v1 tag
  • 选择 2 个仓库灰度验证

🤖 Generated with Claude Code

Summary by CodeRabbit

发布说明

  • 新功能

    • 新增“自动发布”GitHub Action:可从 CHANGELOG 自动解析版本并创建或更新发布,支持草稿与预发布、重复发布保护,并输出版本、发布链接、发布正文与标签。
  • 文档

    • 添加操作使用文档,包含输入/输出参数说明、CHANGELOG 格式与分类映射规则、全量变更链接示例、双语说明及注意事项(如 CRLF 处理与警示)。

✏️ Tip: You can customize this high-level summary in your review settings.

Add reusable composite action for parsing CHANGELOG.md and creating
GitHub releases automatically. This centralizes release logic across
all wuji-technology repositories.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 27, 2026

Walkthrough

新增复合 GitHub Action:actions/auto-release 从仓库的 CHANGELOG.md 解析版本与条目,按类别构建发布正文,计算 Full Changelog 链接,并根据 tag 执行 Release 的创建或更新(upsert),支持 draft 与 prerelease 标志并导出版本与发布链接等输出(50 字内)。

Changes

文件集群 / 文件(s) 变更摘要
自动发布 Action 定义
actions/auto-release/action.yml
新增复合 GitHub Action:读取并解析 CHANGELOG.md(含 CRLF 处理)、从当前 tag 推断版本、按规则分类条目(New Features, Improvements, Bug Fixes, CAUTION 等)、构造 release body(含 Full Changelog 链接与双语处理)、查询并 upsert Release(支持 draftprerelease),并导出 version, release-url, body, tag
自动发布 Action 文档
actions/auto-release/README.md
新增 README:描述功能点(分类映射、CAUTION 段、双语支持、完整变更日志链接、upsert 行为、pre-release 支持等)、使用示例、输入/输出说明、CHANGELOG 格式与分类规则、发布输出示例及高级用法(上传资产、跨仓库同步)。

Sequence Diagram(s)

sequenceDiagram
  participant Runner as Runner
  participant FS as 文件系统 (CHANGELOG)
  participant Tag as Git Ref (refs/tags)
  participant GHAPI as GitHub API
  Runner->>FS: 读取 `CHANGELOG.md`
  Runner->>Tag: 读取当前 tag(refs/tags/...)
  Runner->>Runner: 解析 CHANGELOG,按类别构建 release body 与版本
  Runner->>GHAPI: 查询是否存在 Release(by tag)
  alt Release 存在
    Runner->>GHAPI: 更新已有 Release(upsert:update)
  else Release 不存在
    Runner->>GHAPI: 创建新 Release(upsert:create,使用 draft/prerelease)
  end
  GHAPI-->>Runner: 返回 `release-url`
  Runner-->>Workflow: 输出 `version`, `release-url`, `body`, `tag`
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 我读 changelog 风吹轻,
新版跳出行与名,
一键发布翻新页,
草稿预发随意行,
小兔尾巴摇着庆。

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题清晰准确地概括了主要变更——新增一个自动发布的复合GitHub Action,与变更集内容完全相关。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@actions/auto-release/action.yml`:
- Around line 80-84: The RELEASE_URL shell invocation embeds
steps.parse.outputs.body directly which risks command injection; change the
workflow to pass the parsed body via an environment variable or a temp file
instead of inline interpolation, then have the RELEASE_URL command (the gh
release create invocation) read the release notes from that env var or from
--notes-file and quote it safely (e.g., reference $NOTES or the temp file) so
special characters from steps.parse.outputs.body are not interpreted by the
shell; update the action.yml step that defines RELEASE_URL and the step that
sets NOTES (or creates the temp file) accordingly.
🧹 Nitpick comments (4)
actions/auto-release/action.yml (3)

44-49: heredoc 分隔符 EOF 存在潜在冲突风险

如果 CHANGELOG 内容中恰好包含独立的 EOF 行,会导致 body 输出被截断。建议使用更独特的分隔符。

♻️ 建议的修复
-        {
-          echo "body<<EOF"
-          echo "$BODY"
-          echo "EOF"
-        } >> $GITHUB_OUTPUT
+        {
+          echo "body<<CHANGELOG_BODY_EOF_MARKER"
+          echo "$BODY"
+          echo "CHANGELOG_BODY_EOF_MARKER"
+        } >> $GITHUB_OUTPUT

36-38: 建议通过环境变量传递 changelog-path 输入

body 的问题类似,inputs.changelog-path 直接插值到 shell 中。虽然风险较低(通常是简单路径),但为保持一致性和安全性,建议统一使用环境变量传递。

♻️ 建议的修复
     - name: Parse CHANGELOG
       id: parse
       shell: bash
+      env:
+        CHANGELOG_PATH: ${{ inputs.changelog-path }}
       run: |
-        CHANGELOG="${{ inputs.changelog-path }}"
+        CHANGELOG="$CHANGELOG_PATH"
         VERSION=$(grep -m1 -oP '## \[?\K[0-9]+\.[0-9]+\.[0-9]+' "$CHANGELOG" || echo "")

38-38: 版本号正则表达式不支持预发布版本格式

当前正则 [0-9]+\.[0-9]+\.[0-9]+ 只匹配标准的 major.minor.patch 格式,不支持 1.0.0-beta.11.0.0-rc.1 等预发布版本号。

如果需要支持此类格式,可以扩展正则表达式。

♻️ 支持预发布版本的正则(可选)
-        VERSION=$(grep -m1 -oP '## \[?\K[0-9]+\.[0-9]+\.[0-9]+' "$CHANGELOG" || echo "")
+        VERSION=$(grep -m1 -oP '## \[?\K[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?' "$CHANGELOG" || echo "")
actions/auto-release/README.md (1)

46-58: 建议补充说明支持的版本头格式

根据 action.yml 中的正则表达式 ## \[?\K[0-9]+\.[0-9]+\.[0-9]+,action 同时支持带方括号和不带方括号的版本头格式:

  • ## [1.0.0] - 2026-01-27
  • ## 1.0.0 - 2026-01-27

可以在文档中补充说明这两种格式都支持。

- Add category mapping (Added→New Features, etc.)
- Add CAUTION block for Removed/Deprecated/Security
- Add Full Changelog link generation
- Add Upsert mode (update existing release)
- Add pre-release version support (e.g., 1.0.0-rc4)
- Add CRLF compatibility
- Add Chinese category support
- Update README with complete documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@actions/auto-release/action.yml`:
- Around line 55-58: The code assumes context.ref is a tag and strips
'refs/tags/' without validation; update the logic around context.ref, tag and
version to first check that context.ref startsWith('refs/tags/'), and if not,
log a clear message and stop processing (throw or exit) to avoid downstream
cryptic errors; keep the existing tag/version extraction (const tag =
context.ref.replace('refs/tags/', ''); const version = tag.replace(/^v/, ''))
but only execute them after the validation so non-tag triggers are rejected
early.

Add outputs for downstream steps:
- body: parsed release notes for syncing to other repos
- tag: git tag name for uploading assets

Update README with advanced usage examples:
- Upload release assets with gh release upload
- Sync release to other repositories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@actions/auto-release/action.yml`:
- Around line 140-149: The Full Changelog link hardcodes a "v" prefix (using
`v${prevVersion}`) which breaks repos that use tags without a "v"; update the
link construction in the block that computes allVersions, versionIndex and
prevVersion so it respects the actual tag format: detect whether the current
`tag` starts with "v" and only prefix `prevVersion` with "v" in that case (e.g.
build prevTag = tag.startsWith('v') ? `v${prevVersion}` : prevVersion), then use
`${prevTag}...${tag}` for the compare URL and label instead of always using
`v${prevVersion}`.

@yuanyuanxin yuanyuanxin requested a review from chenjunnn January 27, 2026 12:43
yuanyuanxin and others added 2 commits January 27, 2026 20:45
Validate that the action is triggered by a tag push event.
Fail early with clear error message if triggered by other refs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fail early if tag doesn't start with "v" to ensure consistent
Full Changelog links. Provides clear error message explaining
the required format (e.g., v1.0.0, v1.0.0-rc1).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants