Carbon Design System 版本发布全流程解析:从 prerelease 到 stable 的时间驱动发布指南
2026/9/16 19:16:14 网站建设 项目流程

Carbon Design System 版本发布全流程解析:从 prerelease 到 stable 的时间驱动发布指南

【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon

本文以 IBM Carbon Design System 仓库(monorepo)中的 docs/release.md 为核心,系统讲解其时间驱动的版本发布模型:包括每两周一次的minor稳定版、提前数日发布的preminor/prerelease候选版,以及按需发布的patch安全与缺陷修复版。你将掌握完整的手动发布操作序列(Version Workflow → 打 tag → Release Workflow → npm dist-tag 提升)、v10 旧版本维护流程、手动 patch 发布方法,以及常见故障的排障手段;同时本文结合仓库内 .github/workflows/version.yml、.github/workflows/release.yml、actions/promote/index.js、lerna.json 等源码与配置,深入解释每个步骤背后的自动化原理。

发布模型概述:为什么是"时间驱动"

Carbon Design System 采用**时间驱动(time-based)**而非"攒够功能再发"的发布模型,规则非常简单:

  • 每两周发布一个稳定的minor版本,例如v11.2.0。完整的发布节奏记录在项目的 Release Radar 发布日历中。
  • 每次minor发布前几天,先发布一个 prerelease(预发布版)。这个版本提供了一个集成窗口(integration window),让产品团队在稳定版正式发布前,能够提前集成并验证这些改动。
  • patch版本按需发布,用于承载安全修复和缺陷修复,不遵循固定排期。

这一模型的核心价值在于:既保证了发布节奏的可预期性(每两周一次 minor),又通过 prerelease 给下游产品留出充分的测试缓冲,从而降低稳定版发布引入破坏性变更的风险。

发布团队:release lead 与 sidekick

每一周的发布由**发布团队(Release Team)**协调完成,团队由两名成员组成:

  • Release lead(发布负责人):负责管理发布本身,包括测试(Testing)、发布(Publishing)、支持(Support)三大环节,并在适当时候指导 sidekick 理解并跑通整个发布流程。
  • Release sidekick(发布搭档):如果是第一次进入发布团队,首要任务是学习如何运行发布流程;同时协助 lead 完成测试、发布、支持等各项工作。

两人配合共同保证发布流程的稳定执行,也起到知识传递的作用。

发布流程总览:四个检查点

一次完整的发布周期包含四个检查点:

检查点说明
Prerelease(预发布)发布一个预发布版,用于在稳定化之前测试发布候选
Stable release(稳定发布)将 prerelease 提升为稳定版,通过 npm 包对外可用
Post release(发布后)为最新稳定版提供支持,处理因提升到稳定版而产生的问题
Previous release(旧版本发布)判断 v10 是否有新改动需要发布,如有则发布(v10 已于 2024-09-30 停止支持)

下面按检查点逐一展开实际操作步骤,并标注每一步背后对应的自动化配置。

Prerelease 预发布流程

预发布发生在每个 sprint(迭代)的最后一个周一。此时发布团队需要执行以下操作:

  1. 手动触发 Version Workflow(对应仓库中的 .github/workflows/version.yml),让 Lerna 自动为所有包生成预发布版本号。该工作流通过workflow_dispatch暴露了两个必填输入(见 .github/workflows/version.yml#L8-L23):
    • type:发布类型,可选值为minorpreminorprerelease,默认preminor
    • tag:本次发布对应的 tag 名称,例如v11.2.0-rc.0
  2. 指定preminor作为发布类型;如果是发布下一个 prerelease,则指定prerelease
  3. 提供本次发布的 tag。例如上一个版本是v11.1.0,那么本次预发布的 tag 就是v11.2.0-rc.0(可用仓库 tags 列表确认上一个版本的 tag)。
  4. 审查并批准该工作流自动生成的 Pull Request。该 PR 由peter-evans/create-pull-request动作创建,分支名为release/<tag>,提交信息与标题均为chore(release): <tag>(见 .github/workflows/version.yml#L68-L82)。
  5. 等待 PR 被合并(文档中明确用 🛑 强调此步骤不可跳过)。
  6. 合并后,将上游最新代码拉取到本地:
git checkout main
git pull upstream main
  1. 运行git log查看最近的提交,验证最新提交就是 PR 的发布提交。发布提交的格式为:
chore(release): v11.2.0-rc.0

如果不是该提交,说明 PR 尚未合并,等待合并后重新拉取。按q退出日志。

  1. 给发布提交打上注释 tag,并推送到upstream
git tag -a v11.2.0-rc.0 -m 'v11.2.0-rc.0'
git push upstream v11.2.0-rc.0
  1. 验证推送 tag 是否触发了Release Workflow的运行(见 .github/workflows/release.yml)。该工作流监听v*格式的 tag 推送事件(!v10*被排除,v10 有独立的 v10-release.yml)。

源码解读:Version Workflow 如何生成版本号

从 .github/workflows/version.yml#L50-L61 可以看到,三种发布类型对应三条 Lerna 命令:

# preminor:从当前稳定版生成下一个 minor 的 RC 版本,如 v11.1.0 -> v11.2.0-rc.0 yarn lerna version preminor --no-git-tag-version --preid rc --yes # prerelease:在既有 RC 基础上递增,如 v11.2.0-rc.0 -> v11.2.0-rc.1 yarn lerna version prerelease --no-git-tag-version --preid rc --yes # minor:正式升版,如 v11.2.0-rc.0 -> v11.2.0 yarn lerna version minor --no-git-tag-version --no-push --yes

关键点在于--preid rc:它把预发布标识符固定为rc,使 Lerna 生成的版本形如v11.2.0-rc.0。同时--no-git-tag-version--no-push表示本阶段只修改包版本号、不创建 tag 也不推送,tag 由发布团队在 PR 合并后手动创建,从而保证"版本号变更"与"tag 标记"两个动作解耦。仓库根目录的 lerna.json 配置了"version": "independent"(每个包独立版本号)、"npmClient": "yarn",以及提交信息模板"chore(release): %s";它还通过ignoreChanges排除了actions/****/docs/****/e2e/****/*.md等目录,避免文档或测试改动误触发版本号变更。

再次发布下一个 prerelease

当一个 prerelease 发布后,如果需要发布后续的候选版(例如从v11.12.0-rc.0v11.12.0-rc.1),重复上述 Prelease 步骤,但发布类型改为prerelease而不是preminor

Stable release 稳定发布流程

稳定发布发生在最后一个周三,并在当天稍晚完成。它必须发生在 prerelease 已经过测试和验证之后。流程如下:

  1. 手动触发Version Workflow
    • 指定minor作为发布类型
    • 提供本次发布的 tag。例如上一个版本是v11.1.0-rc.0,则本次 tag 为v11.1.0
  2. 审查并批准工作流自动生成的 PR。
  3. 🛑等待 PR 被合并
  4. 合并后拉取上游最新代码:
git checkout main
git pull upstream main
  1. 运行git log验证最新提交是发布提交(格式如chore(release): v11.10.0),按q退出。
  2. 给发布提交打 tag 并推送
git tag -a v11.2.0 -m 'v11.2.0'
git push upstream v11.2.0
  1. 验证推送是否触发了Release Workflow的运行。

Release Workflow 做了什么

推送v*tag 后,.github/workflows/release.yml 会被触发,它做四件关键的事:

  1. 构建与质量门禁:安装依赖、构建项目、构建 Storybook 并启动本地服务、运行 Playwright AVT(无障碍自动化测试,--grep @avt)、执行yarn ci-check等,确保发布产物质量达标。
  2. nextdist-tag 发布到 npm:执行yarn lerna publish from-package --dist-tag next --no-verify-access --yes(见 .github/workflows/release.yml#L68-L71)。注意发布是落到next标签上,而不是直接进latest
  3. 自动提升到latestpackages任务(needs: build)仅在 tag不包含-rc时执行(if: contains(github.ref_name, '-rc') == false),它调用仓库内置的 actions/promote 动作,把所有已变更包的 npm dist-tag 从next提升为latest。这正是文档中"自动将带新版本号的 Carbon 包提升到 latest"的实现来源。
  4. 创建 GitHub Release:通过github.rest.repos.createRelease为当前 tag 创建 Release 记录,并默认标记为 prerelease。

Promote 动作的内部逻辑

actions/promote/index.js 的实现细节值得展开:

  • 它递归遍历所有 workspace,跳过private字段为 true 的包;
  • 存在一个 denylistcarbon-components@carbon/icons-vue不会被自动提升(见 actions/promote/index.js#L14),这与文档中"手动 patch 发布时不要对 carbon-components 执行 dist-tag 提升"的提醒完全对应;
  • 对每个包,它查询 npm registry 的dist-tags.latest,若与当前版本不一致,就执行npm dist-tag add <name>@<version> latest(支持DRY_RUN参数,见 actions/promote/action.yml);
  • 完成后在 Actions summary 中输出每个包的 Previous / Latest 对比表。

发布后的收尾动作

Release Workflow 成功后,发布团队还需完成:

  1. 验证包已在 npm 上提升到latest(例如检查@carbon/react)。
  2. 用 Carbon CLI 生成 changelog 并更新最新 Release 的说明。在 monorepo 根目录执行:
./packages/cli/bin/carbon-cli.js changelog v11.5.0..v11.6.0

changelog命令位于 packages/cli/src/commands/changelog.js:它会先从 upstream 拉取最新 git 信息、获取 workspace 内所有包,然后按<range>(如v11.5.0..v11.6.0)解析起止 tag,为范围内每个包生成 changelog,并询问是否复制到剪贴板(可用-n/--noPrompt跳过交互)。 3.在 GitHub Release 页面上取消勾选 "this is a prerelease",将发布正式标记为稳定版。 4.在 Slack 中发布发布公告,渠道包括#carbon-announcements#carbon-design-system#carbon-react#carbon-web-components

文档还提供了一份可直接复用的 Slack 公告模板(Markdown 版与 Block Kit Builder 版),核心结构为:版本号链接 + 本次更新要点列表 + 引导用户查看 Release Radar + 反馈渠道 + 致谢。

更新 gatsby-theme-carbon 与 carbon-website

稳定版 Release Workflow 完成后,会自动触发deploy-packages工作流(通过repository_dispatchdeploy-packages事件,见 .github/workflows/release.yml#L102-L105),对应的 .github/workflows/deploy-packages.yml 会分别在design-language-websitegatsby-theme-carbon两个仓库中自动升级 Carbon 依赖并打开 PR。后续操作:

  • 审查、批准并合并gatsby-theme-carbon仓库中由该动作生成的 PR,确认本次发布没有破坏性变更。如果上一轮发布的 PR 尚未合并,已有 PR 会被自动更新。
  • gatsby-theme-carbon仓库运行release-it工作流,触发gatsby-theme-carbon自身的发布。
  • 检查gatsby-theme-carbon是否已发布、其版本是否基于最新 Carbon。
  • 运行 Carbon 官网(carbon-website)仓库的 "Update Carbon and gatsby-theme-carbon deps" 工作流,自动打开更新依赖的 PR。
  • 审查并批准该 PR。

Post release:发布后的支持与问题响应

发布后需要:

  • 更新 Release Radar 发布日历页面,记录本次发布的实际情况。
  • 密切监控 Slack 渠道与 GitHub issues:因为包从next切到latest后,可能暴露此前未发现的破坏性变更。

针对不同的问题类型,文档给出了两条典型的处理策略:

  • Hotfix(热修复):如果问题自包含、可以快速解决,走一次 patch 发布是最直接的解决方式;
  • Revert to previous stable release(回滚到上一稳定版):如果问题无法快速修复、或修复时间不可控,回滚到上一个稳定版是更稳妥的选择。

Manual Patch Release:手动补丁发布

当需要做一次计划外的(off-cycle)补丁发布、修复上一个版本中意外引入的缺陷时,按以下步骤执行(这也是理解 Lerna 手动版本控制的最佳实操案例):

  1. 进入本地 monorepo,先同步最新状态:
git fetch upstream
  1. 检出要打补丁的目标 tag(通常是最新发布 tag):
git checkout vX.Y.Z
  1. 基于该 tag 创建新分支,分支名使用"目标发布版本号",即当前版本号递增+0.0.1(补丁位):
git checkout -b release/vX.Y.Z
  1. 把希望纳入补丁的提交(hotfix)cherry-pick 进来:
git cherry-pick ######
  1. 运行git log验证最新提交依次是:tag 对应的发布提交 + cherry-pick 进来的提交,然后按q退出。

  2. 用 Lerna 为自上次版本以来有变更的包统一升 patch 版本:

yarn lerna version patch --no-git-tag-version --no-push --yes
  1. 检查变更文件,确认所有受影响的包版本都只增加了+0.0.1(patch 位)。
  2. 运行yarn install更新依赖锁。
  3. 确认此刻所有文件变更只涉及package.jsonyarn.lock,不应有其他文件被改动。
  4. 提交并推送:
git add -A
git commit -m 'chore(release): vX.Y.Z'
git push --set-upstream origin release/vX.Y.Z
  1. 用该分支创建 PR:base分支设为main,标题为chore(release): vX.Y.Z,描述写明包含的 hotfix 提交。
  2. 关闭这个 PR(不合并),并在关闭时注明:这是手动发布,该 PR 仅用于在 GitHub 历史中记录发布,无需合并。
  3. 给发布提交打 tag 并推送到 upstream:
git tag -a vX.Y.Z -m 'vX.Y.Z'
git push upstream refs/tags/vX.Y.Z
  1. 验证推送触发了 Release 工作流并成功,且包以nexttag 发布到 npm。
  2. 如果版本号正确,手动把受影响的包提升到latest注意
    • 不要对carbon-components包执行此操作(与 actions/promote/index.js 中的 denylist 一致);
    • 必须使用每个包各自生成的具体版本号,而不是 GitHub 上的发布 tag;
    • 建议以carbon-bot身份登录 npm CLI,避免鉴权问题。
  3. 对每个包执行(将carbon-components-react替换为实际包名):
npm dist-tag add carbon-components-react@vX.Y.Z latest
  1. 验证 npm 上包已提升到latest
  2. 在 monorepo 根目录用 Carbon CLI 生成 changelog 并更新 Release 说明:
./packages/cli/bin/carbon-cli.js changelog vA.B.C..vX.Y.Z

值得一提的是,仓库还提供了对应的自动化补丁工作流.github/workflows/version-patch.yml:它接受tagexisting-tag以及最多 5 个待 cherry-pick 的提交 SHA(commit-1commit-5),自动完成"检出既有 tag → 创建 release 分支 → cherry-pick →lerna version patch→ 提交 → 打 tag 并推送"的全过程,可以作为手动流程的参考实现。

Previous releases(v10):旧版本维护流程

从 2022 年 3 月 v11 首发,到2024 年 9 月 30 日,Carbon 一直对上一个主版本(v10)提供维护支持。v10 在此期间只在被请求时接收缺陷修复,以及关键安全更新。所有 v10 代码与资源已在 2024 年 9 月 30 日停止支持(End of Support)

文档明确注明:以下 v10 发布流程相关内容仅出于留档(posterity)目的保留,应在下一个主版本发布时从文档中移除。本仓库中对应的自动化工作流 .github/workflows/v10-version.yml 与 .github/workflows/v10-release.yml 至今仍保留,供理解历史机制参考。

如何判断 v10 是否需要发布

  1. 打开仓库的 compare 页面;
  2. 在 "base" ref 下拉框的 "tags" 标签页中,选择最近的v10.xtag;
  3. 在 "compare" ref 下拉框中选择v10分支;
  4. 查看 diff:
    • 如果 diff 为空,说明 v10 无需发布;
    • 如果包含一串提交,说明需要发布新的v10.x版本。

同时检查以v10为 base 的 PR 队列——可能存在已打开、等待合并、可纳入本次发布的 PR。

发布 v10 旧版本

  1. 进入本地 monorepo,检出 v10 分支并同步:
git checkout v10
git pull upstream v10 --tags
  1. 创建 release 分支:
git checkout -b release/vX.Y.Z
  1. 安装依赖并确保工作区干净(git status)。
  2. 运行 Lerna 为有变更的包升 patch 版本:
yarn lerna version patch \ --no-push \ --no-git-tag-version
  1. 仔细核对版本增量:作为 patch 发布,不应包含破坏性变更(如v10.14.0 → v11.0.0),也不应包含 minor 变更(如v10.59.1 → v10.60.0)。确认无误后按y继续。
  2. 快速校验:运行yarn install --immutable确认所有版本已正确递增(有时需要手动更新根目录package.json)。
  3. 运行yarn install,提交并推送:
git add -A
git commit -m 'chore(release): vX.Y.Z'
git push --set-upstream origin release/vX.Y.Z
  1. 创建 PR:base分支设为v10,标题chore(release): vX.Y.Z
  2. 🛑 等待 PR 合并后,拉取最新代码并验证最新提交是发布提交(如chore(release): v10.59.1)。
  3. 打 tag 并推送:
git tag -a vX.Y.Z -m 'vX.Y.Z'
git push upstream vX.Y.Z
  1. 验证推送触发了 release 动作,且包以v10-nexttag 发布到 npm(v10 使用独立的 v10-release.yml,其发布命令为yarn lerna publish from-package --dist-tag community --no-verify-access --yes,发布到communitydist-tag)。
  2. 在 monorepo 根目录生成 changelog:
./packages/cli/bin/carbon-cli.js changelog vA.B.C..vX.Y.Z

为单个包发布新 major

某些情况下,monorepo 中单个包需要 major 版本升级,而不需要全仓库统一升 major。例如:eslint-config-carbon需要新 major,而其他包只升 patch,且仓库 tag 保持在当前 major(v11.x)不变。

操作方式为手动版本控制:

  1. 切到maingit pull upstream main拉取最新;
  2. 创建版本分支,如git checkout -b release/v11.23.1
  3. 运行yarn lerna version --no-git-tag-version --no-push
  4. 在交互式提示中为每个包选择合适的版本增量;如果某个包不需要变更版本,选择Custom Version并输入其现有版本号保持不变;
  5. 交互完成后运行yarn install更新yarn.lock
  6. 提交chore(release): v11.23.1,推送并打开 PR;
  7. 合并后,从"🛑 等待 PR 被合并"这一步开始,走 Stable release 的后续流程:打 tag 并触发自动化发布工作流。

Troubleshooting:常见故障排障指南

Version 工作流成功但 PR 未创建

查看工作流日志——很可能是Lerna 没有检测到需要发布的变更。这种情况常发生在:自最近一个 tag 发布以来,main分支没有新增内容。合并一个 PR 后重新运行工作流(不要重跑上一次)即可解决。

Version 工作流失败

如果 Version 工作流失败且无法定位原因,只要你有仓库的 push 权限,就可以在本地按工作流文件中的命令手动执行:

  1. 在干净的工作区拉取main最新代码并创建release/vX.Y.Z分支:
git checkout main
git pull upstream main
git checkout -b release/vX.Y.Z
yarn install
yarn build
  1. 依次执行 version.yml 中的其余命令(yarn buildyarn lerna ...yarn install等)。
  2. 提交并推送到 PR,此时你与"Version 工作流成功"处于同一进度:
git add .
git commit -m "chore(release): vX.Y.Z"
git push

Release 工作流失败

同理,只要有仓库 push 权限和 npm 发布权限,可以在本地复现:

  1. 拉取对应 tag:git checkout vX.Y.Z
  2. 按 release.yml 中的命令顺序依次执行;
  3. 成功后,手动为对应 tag 创建 GitHub Release,并附上生成的 changelog。

收到 unpkg 链接失效的报告

这类问题通常是 unpkg 的默认行为导致的:https://unpkg.com/carbon-components/*会解析为latesttag 对应的版本。如果latesttag 被误打到了v11.x版本上,使用非版本化 unpkg 链接的用户就会解析到 v11 包——而 v11 包不再包含编译后的样式表,从而出现样式丢失。

修复方法是:把latesttag 重新指回v10.x

npm dist-tag add carbon-components@10.X.Y latest

建议以carbon-bot身份登录 npm CLI 以避免鉴权问题。同时应引导用户养成给包名追加版本号前缀的习惯,确保 unpkg 始终解析到最新的 v10 版本:

https://unpkg.com/carbon-components@10/css/carbon-components.min.css https://unpkg.com/carbon-components@10/scripts/carbon-components.min.js

手动部署 v10 Storybook 时,v11 的 Storybook 被发布到了 v7-react 站点

原因是对应的部署工作流必须从v10分支运行:手动触发时,务必在分支下拉框中选择v10,而不是默认分支,否则产物会发布到错误的域名。

结语:一条贯穿"自动化 + 人工把关"的发布链路

纵观整个发布流程,Carbon 的发布体系呈现出清晰的"自动化为主、人工把关为辅"的设计:Version Workflow 负责批量生成版本号与 release PR,Release Workflow 负责构建、测试、以next发布并自动提升到latest,Promote 动作内置了包名 denylist 防止误提升,deploy-packages通过repository_dispatch联动下游网站仓库;而人工环节(审查 PR、验证发布提交、打 tag、更新 changelog、发公告)则构成了质量与合规的最后一道防线。理解这条链路,无论是为 Carbon 贡献代码、维护自己的 monorepo 发布体系,还是排查发布问题,都能做到心中有数、按图索骥。

【免费下载链接】carbonA design system built by IBM项目地址: https://gitcode.com/GitHub_Trending/carbo/carbon

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询