深入解析 Storybook 的自动化发布体系:分支策略、Release PR 与版本管理全流程

深入解析 Storybook 的自动化发布体系:分支策略、Release PR 与版本管理全流程
深入解析 Storybook 的自动化发布体系分支策略、Release PR 与版本管理全流程【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本文以 Storybook 官方的发布规范 RELEASING.md 为主体完整拆解该 monorepo 中非补丁发布与补丁发布两条发布流水线的运作原理、发布者的标准操作步骤、各类版本升级场景的输入组合以及紧急情况下手动发布的完整操作序列。读完本文你将能够理解 Storybook 是如何用 GitHub Actions 与 NodeJS 脚本把changelog 生成、版本号升级、npm 发包、GitHub Release 创建这条复杂链路自动化起来的并能独立复述其分支策略与 canary 发布机制。1. 发布体系总览Storybook 的发布过程分为两大类非补丁发布Non-patch releases发布next分支上的任何内容既可以是预发布版prerelease也可以是正式版stable补丁发布Patch releases从next挑选需要打回当前稳定小版本main的内容。整个流程建立在自动创建的Release Pull Requests之上当这些 PR 被合并时就会触发一个新版本的发布。由核心团队成员轮值担任的发布者Releaser会在当前 Release PR 中执行发布流程。该流程由三部分实现NodeJS 脚本位于 scripts/release/三个 GitHub Actions 工作流PreparenextPRPrepare patch PRPublish所有 CLI 入口都注册在 scripts/package.json 中以release:前缀命名例如npm script对应实现作用yarn release:versionversion.ts计算并写入新版本号yarn release:write-changelogwrite-changelog.ts生成并写入 changelogyarn release:pick-patchespick-patches.ts挑选并 cherry-pick 补丁 PRyarn release:publishpublish.ts构建并发布所有 npm 包yarn release:is-pr-frozenis-pr-frozen.ts判断 Release PR 是否被冻结yarn release:unreleased-changes-existsunreleased-changes-exists.ts检查是否存在可发布的变更yarn release:label-patcheslabel-patches.ts给已发布的补丁 PR 打上 patch:done 标签yarn release:generate-pr-descriptiongenerate-pr-description.ts生成 Release PR 的描述文本yarn release:cancel-preparation-runscancel-preparation-runs.ts发布时取消仍在运行的准备任务1.1 分支策略理解发布结构前必须先理解分支模型所有开发都在next分支上进行新特性和 bug 修复都进入这里。该分支的内容将进入下一个预发布版如v7.1.0-alpha.22main分支保存当前稳定版的内容如v7.0.20。当一个变更同时需要进入下一个 minor/major 和当前 patch 版本时改动合入next然后给该 PR 打上patch:yes标签发布工作流便会将其挑选回main。这样做的目的是变更先在预发布版中被验证再进入稳定版真正的预发布不直接发生在next或main上而是分别发生在next-release与latest-release上。这一间接层的原因见 第 8 节。简化后的分支关系图如下原文档中的 mermaid 图2. Release Pull Requests发布的接口两个 GitHub Actions 工作流会自动创建两类发布 Pull Request每类一个。这些 PR 充当 Releaser 创建新版本的接口。高层流程为当一个 PR 合入next或向next推送提交时两个 Release PR 都会被重新生成它们创建一个新分支——version-(patch|non-patch)-from-CURRENT-VERSION按版本策略计算要升级到的版本号用检测到的全部变更更新CHANGELOG(.prerelease).md提交所有内容强制推送force push向next-release或latest-release发起/更新 Pull Request。几个关键点PR 会在next的任何变更上重新生成也可以手动触发见 第 4.4 节变更是被 force push 到分支的因此合并前对发布分支的任何手动修改都有可能在别人合入next的新变更而触发工作流时被覆盖。为避免这种情况要给 PR 打上freeze标签changelog 在准备阶段就已提交但包的版本号升级和发布要等到后续阶段Release PR 的目标不是其工作分支next/main而是next-release/latest-release。从源码看冻结机制由 is-pr-frozen.ts 实现它根据code/package.json中的当前版本拼出分支名version-${patch ? patch : non-patch}-from-${version}fetch 该远端分支通过其 HEAD commit 找到对应的 open PR再检查该 PR 是否带有freeze标签。两个 prepare 工作流都在开头调用它——例如 prepare-non-patch-release.yml 中的 Check if pull request is frozen 步骤若frozen true且触发事件不是workflow_dispatch工作流会执行gh run cancel取消自身。这正是freeze 标签不会阻止手动触发这一行为的底层实现。2.1 补丁发布Patch Releases工作流prepare-patch-release.yml补丁发布通过 cherry-pick 合入next但尚未发布、且带patch:yes标签的所有 PR 的merge commit来创建。有些场景下即使内容不算可发布也希望把 PR 挑选回main与 non-patch 准备不同patch 发布不会因内容不可发布而取消。例如变更只涉及文档和/或内部构建系统时创建新 patch 版本可能没意义但把变更带回main是部署文档到生产文档站的唯一途径也可能需要把内部 CI 的修复 cherry-pick 回去。在这类所有 cherry pick 都不可发布的情况下准备工作流会创建一个merging PR而不是 releasing PR——它不升版本、不更新 changelog只是把变更 cherry-pick 过去允许你把它合并进latest-release→main。这一点在 prepare-patch-release.yml 中有对应实现当has-changes-to-release false时它会创建一个标题为Release: Merge patches to main (without version bump)的 PR。准备工作流会顺序地把每个 patch PR cherry-pick 到它的分支上。如果某次 cherry-pick 因冲突或其他原因失败会被忽略并继续处理下一个 PR所有失败的 cherry-pick 都会列在 Release PR 的描述中工作流通过failed-cherry-picks输出传给generate-pr-description由 Releaser 在发布过程中手动挑选。当main与next分歧越大即距上一次稳定 major/minor 发布越久这类冲突就越常见。与 non-patch 流程类似patch 准备工作流会从main创建名为version-patch-from-CURRENT-STABLE-VERSION的新分支并开一个目标为latest-release的 PR。当 Releaser 合并该 PR 后发布工作流最终会把latest-release合并进main。下面的示例中一个 feature 和两个 bug 修复合入了next只有两个 bug 修复带 patch:yes 标签因此只有它们进入新的7.0.19。注意被 cherry-pick 的是合入next的 merge commit而不是 bugfix 分支上的原始提交2.2 非补丁发布Non-patch Releases工作流prepare-non-patch-release.yml非补丁发布基于next分支的全部内容。changelog 通过检查 git 历史生成——查找当前预发布版位于next-release与next的HEAD之间所有的 commit 和 PR。这一逻辑对应 unreleased-changes-exists.ts 与 get-changes.ts后者以--first-parent拉取from默认是最新版本 tag 对应 commit到to默认HEAD之间的提交再逐一反查其关联 PR 的标题与标签。默认的版本策略是递增当前预发布编号见 3.1 节。如果当前没有预发布编号即刚发布了一个稳定的 minor/major 版本默认策略会走一次 patch bump例如从7.2.0到7.2.1-0。只有当确实存在可发布变更时才会创建next-PR。带 build 或 documentation 标签的内容不被视为可发布见 6.3 节不属于用户可见的变更因此没有发布意义。准备工作流会从next创建名为version-non-patch-from-CURRENT-NEXT-VERSION的分支开一个目标为next-release的 PRReleaser 合并后发布工作流会把next-release合并回next。示例一个 feature 和一个 bugfix 被创建并发布为新的7.1.0-alpha.29。图中方点square dots标出的提交都会参与 changelog 生成2.3 发布Publishing工作流publish.yml当 non-patch 或 patch 发布分支被合并进latest-release/next-release时发布工作流被触发。它依次执行以下任务按已准备好的 PR 中的计划为所有包升级版本号安装依赖并构建所有包将包发布到 npm若是补丁发布给所有相关 PR 打上patch:done标签在发布分支latest-release或next-release上创建版本 tag并新建 GitHub Release把发布分支合并进核心分支main或next若是补丁发布把CHANGELOG.md的变更从main同步到next。出于安全考虑该工作流运行在名为Release的 GitHub environment 中publish.yml的environment: Release持有发布到storybooknpm 组织所需 token且只能从四个核心分支访问main、next、latest-release、next-release。对照 publish.yml 的实际步骤可以观察到文档描述的每一步都有对应实现Apply deferred version bump and commit读取code/package.json中的deferredNextVersion若存在则执行yarn release:version --apply --verbose提交Bump version from ... to ... [skip ci]并推回发布分支。这解释了为什么 prepare 阶段只做延迟版本升级见 3.2 节Check if publish is needed通过yarn release:is-version-published查询 registry已发布则跳过Check release vs prereleaseyarn release:is-prerelease决定 dist tag 是next还是latest以及 GitHub Release 是否标记为 prereleasePublish调用yarn release:publish --tag next|latestLabel patch PRs as picked仅在latest-release分支上执行yarn release:label-patches且刻意设置continue-on-error但失败时通过 Discord webhook 告警——注释说明这是因为吞掉权限错误曾导致已发布的 PR 再次出现在后续 patch changelog 中Create GitHub Release若vversion的 release 已存在则跳过否则用 changelog 作为 notes 创建Merge把发布分支 merge 回next或main对于从next-release发布的正式版非 prerelease还会把nextforce push 到latest-release和main保证三个分支内容一致Sync CHANGELOG.md from main to next补丁发布后把main上的CHANGELOG.md同步提交到next即上面流程的第 7 步。从 publish.ts 的源码可以看到实际的发包命令是yarn workspaces foreach --all --parallel --no-private ... npm publish --provenance --tolerate-republish --tag tag即并行发布所有非 private 工作区并附带 npm provenance 信息。关于容错原文档说任意数量的包发布失败会重试 5 次跳过已发布的包而当前源码中重试上限为MAX_PUBLISH_ATTEMPTS 3失败后会先解析 registry 报错识别已被接受的包、再轮询 registry间隔 15 秒、最长 15 分钟等待 staged 版本可见只针对缺失的包重试。可以推断这里的数字随源码演进有过调整实际行为以仓库代码为准。3. 版本策略与输入组合3.1 各场景对应的输入存在多种类型相同但做法略有不同的发布场景如何触发由 prepare 工作流的workflow_dispatch输入决定。prepare-non-patch-release.yml 定义了release-type必选默认prerelease与pre-id可选字符串两个输入场景版本变化示例需要的输入预发布默认策略7.1.0-alpha.12→7.1.0-alpha.13无直接触发即可预发布晋级7.1.0-alpha.13→7.1.0-beta.0Release type:PrereleasePrerelease ID:betaMinor/Major 正式版7.1.0-rc.2→7.1.0或8.0.0-rc.3→8.0.0Release type:Patch/Minor/MajorPrerelease ID: 留空新 major/minor 的首个预发布7.1.0→7.2.0-alpha.0或8.0.0-alpha.0Release type:Preminor/PremajorPrerelease ID:alpha稳定版 patch默认 patch 场景7.1.0-alpha.13的子集 →7.0.14走 patch 工作流cherry-pick 到main更早版本的 patch子集 →6.5.14纯手动找到对应 tag 检出后按紧急发布流程操作即将发布的 patch 的预发布7.0.20→7.0.21-alpha.0官方文档中未定义流程按需处理不带版本升级的main合并无所有未挑选的 patch PR 都不可发布时自动发生patch PR 标题变为 Merge patches to main (without version bump)其中 Minor/major 场景是特殊的它目标分支为latest-release而非next-release因此完成后合并进main而不是next完整路径是next→version-non-patch-from-CURRENT-VERSION-ON_NEXT→latest-release→main。3.2 版本号升级的源码级细节版本计算的真正实现在 version.ts 中。它用commander定义 CLI 参数用zod做组合校验-R, --release-type major|minor|patch|prerelease|premajor|preminor|prepatch要使用的升级类型zod enum 限定这 7 种取值-P, --pre-id id预发布标识符如alpha、beta、rc。只有premajor/preminor/prepatch/prerelease可以携带 pre-id否则校验直接报错-E, --exact version直接指定精确版本必须是合法 semver与--release-type互斥二者必须恰好提供一个-D, --deferred不立即改各包的版本而是把目标版本写入code/package.json#deferredNextVersion-A, --apply读取并移除deferredNextVersion真正执行升级。它与--deferred、--exact、--release-type均互斥若code/package.json中没有deferredNextVersion会抛错-V, --verbose详细日志。真正执行升级时version.ts 中的bumpVersionSources与bumpAllPackageJsons新版本会写入四类位置code/package.json 的version字段这也是所有脚本读取当前版本的单一来源code/core/src/manager-api/version.tscode/core/src/common/versions.ts所有工作区包的package.json通过getCodeWorkspaces枚举随后执行yarn install --modeupdate-lockfile刷新锁文件。版本号的计算本身委托给semver.inc(currentVersion, releaseType, preId)。version.test.ts 中的参数化用例精确覆盖了第 3.1 节表格里的每种输入组合例如prerelease1.1.1-alpha.5→1.1.1-alpha.6prereleasepre-id: beta1.1.1-alpha.10→1.1.1-beta.0预发布晋级patch1.1.1-rc.10→1.1.1rc 晋级到稳定preminoralpha1.1.1→1.2.0-alpha.0新 minor 的首个预发布premajoralpha1.1.1→2.0.0-alpha.0apply从deferredNextVersion: 1.2.0应用出1.2.0同时删除该字段。测试还断言了--deferred模式只写一次文件即仅设置deferredNextVersion不触碰其他文件这解释了 prepare 工作流为何能在准备阶段安全地记录目标版本、而把真正的版本号升级推迟到 publish 工作流执行。4. 发布者操作手册How to Release以下步骤同样会写在 Release PR 的描述中以指导经验不足的 Releaser。高层工作流找到准备好的 Pull Request冻结 Pull Request对已合并的 PR 做处理revert、重命名、重新打标重新触发工作流让第 3 步的变更生效做必要的手动修改合并确认 Publish 工作流成功结束4.1 步骤一找到准备好的 Pull Request按要发布的类型查找对应标题的 PRRelease: Prerelease|Minor|Major NEXT-VERSION—— 来自next的发布标题由工作流按Release: ${CAPITALIZED_RELEASE_TYPE} ${TITLE_SUFFIX}${NEXT_VERSION}拼出见 prepare-non-patch-release.yml 的 Create or update pull request 步骤Release: Patch NEXT-VERSION—— 补丁发布Release: Merge patches to main (without version bump)—— 不升版本的补丁合并。4.2 步骤二冻结 PR 并运行 CI给 PR 打上freeze标签阻止后续合入next时准备工作流再次运行这样你可以放心修改而不用担心被他人的提交覆盖。由于is-pr-frozen检查只在非workflow_dispatch事件时生效freeze 并不会取消手动触发的运行。同时需要加ci:daily标签触发 CI 运行会在全量 CI 以及任何变更上重跑。默认不跑 CI是为了避免在真正创建新版本之前产生不必要的重复运行。4.3 步骤三QA 每一个已合并的 Pull Request确认发布内容正确关键检查项变更是否适合本次版本升级例如minor 预发布里不允许 breaking changepatch 发布里不应混入新 feature。若不适合revert 该 PR 并通知作者。patch 发布中若某 PR 带 patch:yes 但你不想让它进本次发布比如对其信心不足、还需维护者更多输入可先移除该标签并继续发布记得重新触发工作流发布完成后再把标签加回去让它进入下一次发布。PR 标题是否正确PR 标题会进入面向用户的 changelog源码层面get-changes.ts 的getChangelogText直接用 PRtitle生成- ${title} - ${pull}, thanks ${user}!条目必须准确、可读遵循[Area]: [Summary]模式——Area 是被改动部分的仓库区域Summary 是改了什么。容易把 Area 与标签混淆build标签表示改动是内部实现但 build不是合适的 Area 写法Area 可以是 Core 或 CI。跨多处改动如升级依赖时凭最佳判断原则是越精确日后越易读。PR 标签是否正确标签会决定 PR 是否进入 changelog见 6.3 节。补丁是否已经在某个预发布版中发布过若某补丁 PR 还没进过任何预发布版应先创建一个预发布版再打 patch。这并非技术硬性要求而是良好实践——确保变更没有先弄坏预发布版就被发到稳定版。4.4 步骤四重新触发工作流对 PR 标题、标签的修改甚至 revert都不会反映在 Release PR 中——因为工作流只在向next推送时触发PR 元数据变化不会触发。因此第 3 步只要有改动就必须手动重新触发工作流来重新生成 changelog 与版本升级。若没做任何改动可跳过本步。重要触发工作流会 force push 到发布分支所以必须在手动修改下一步之前执行否则手动修改会被覆盖。另外注意重新触发后冻结之后合入next的新内容也会进入 Release PR不能假设还是冻结时看到的那份内容。触发时始终选择next分支作为 base除非你非常清楚自己在做什么。手动触发 non-patch 工作流时可附加输入——Release type 下拉框prerelease/prepatch/preminor/premajor/patch/minor/major与 Prerelease ID 文本框这正是切换版本策略的地方见 3.1 节4.5 步骤五手动修改必要时可以合法地直接向发布分支推送手动修改——例如以自动化工具无法完成的方式修改 changelog或为让发布能进行而做关键变更。这些修改会随发布一起合并进next/main。但官方建议尽可能使用自动化流程以保证 GitHub 是唯一事实来源single source of truth让 PR 与 changelog 保持同步。4.6 步骤六合并冻结 PR 时已经触发过一次 CI 运行若其为绿色即可合并。CI 失败时与核心团队协商——这些 Release PR 几乎是next/main的精确拷贝所以正常情况下 CI 结果应与核心分支一致。4.7 步骤七等待 Publish 工作流结束合并 PR 会触发 publish 工作流完成最终的版本升级与发布。Releaser 有责任确保它成功结束应关注到结束——失败时会有 Discord 通知也可以用那个来监控。5. 特殊发布场景5.1 向更早的 minor 版本发布如果要把变更发布到不是最新的旧 minor 版本必须本地手动完成。以当前最新是8.4.0要发v8.3.7为例完整 18 步流程检出匹配目标 minor 的最新 tag 并建分支git fetch --all --tagsgit checkout tags/v8.3.6 -b patch-8-3-7做需要的变更通常是从修复分支 cherry-pickyarn install用yarn task --task compile --no-link构建code下的所有包提交并推送在 CircleCI 上手动触发 daily CITrigger PipelinePipeline: storybook defaultConfig Source: storybookBranch 设为你的分支添加参数nameworkflow、valuedaily等待 CI 成功升级所有包版本cd scripts然后yarn release:version --release-type patch提交git commit -m Bump version from CURRENT_VERSION to NEXT_VERSION MANUALLY在CHANGELOG.md中添加描述变更的新条目提交git commit -m Update CHANGELOG.md with NEXT_VERSION MANUALLY确认对 Storybook npm 包有写权限——需要是storybookorg 的管理员且对 org 外的包也有权限最简单的确认方式是能看到storybook/react-vite、storybook、sb、create-storybook这些包的 Settings 页获取或生成 npm access token需授予storybookorg 与上述 org 外包的访问权用YARN_NPM_AUTH_TOKENNPM_TOKEN yarn release:publish --tag tag-for-publishing-older-releases --verbose发布所有包到 npm 确认新版本的 dist tag 为tag-for-publishing-older-releasespush手动创建 GitHub Release新建 tagvVERSION如v8.3.7target 为你的分支previous tag 为vPREVIOUS_VERSION如v8.3.6标题vVERSION描述为CHANGELOG.md中新增内容并取消勾选 Set as the latest release把 changelog 变更 cherry-pick 到next使其真正可见检出next→ cherry-pick 你的 changelog 提交 → push。5.2 紧急情况下本地手动发布自动化可能坏掉需要一个应急逃生舱当自动化失效时可以完全在本地运行整个发布流程不必创建 PR、也不必把准备与发布拆开一次做完但仍须遵守正确的分支策略。两种选择本地准备 自动 publish 工作流或全流程本地完成。后者需要 npm registry 的 token设为YARN_NPM_AUTH_TOKEN。可以查看各工作流实际执行了什么并照搬以下是模拟自动化流程的通用步骤可酌情偏离开始前先确保工作树干净git clean -xdf。从next或mainpatch创建新分支拉取所有 taggit fetch --tags origin安装依赖yarn task --taskinstall --start-frominstallcd scripts若 patch 发布cherry-pickyarn release:pick-patches根据上一步输出手动 cherry-pick 需要的补丁升级版本若计划用自动 publish即止步于第 12 步用 deferred 方式yarn release:version --verbose --deferred --release-type RELEASE_TYPE --pre-id PRE_ID若全程本地发布不要deferyarn release:version --verbose --release-type RELEASE_TYPE --pre-id PRE_ID查看变更列表作为自己的 to-doyarn release:generate-pr-description --current-version CURRENT_VERSION --next-version NEXT_VERSION_FROM_PREVIOUS_STEP --verbose写 changelogyarn release:write-changelog NEXT_VERSION_FROM_PREVIOUS_STEP --verbosegit add .提交git commit -m Bump version from CURRENT_VERSION to NEXT_VERSION_FROM_PREVIOUS_STEP MANUALLY合并进发布分支git checkout latest-release | next-releasegit pullgit merge PREVIOUS_BRANCHgit push origin若自动 publish 仍在工作此时应已接管可跳过后续步骤cd ..发布YARN_NPM_AUTH_TOKENNPM_TOKEN yarn release:publish --tag next OR latest --verbose若 patch 发布yarn release:label-patches手动创建 GitHub Releasetag 为新版本target 为latest-release或next-release合并进核心分支git checkout next|maingit pullgit merge next-release|latest-releasegit push origin若 patch 发布把CHANGELOG.md同步到nextgit checkout nextgit pullgit checkout origin/main ./CHANGELOG.mdgit add ./CHANGELOG.mdgit commit -m Update CHANGELOG.md for vNEXT_VERSIONgit push origin6. Canary 发布与 FAQ6.1 Canary Releases任何 PR 都可以在开发过程中被多次发布为 canary 版本。这是在不通过包管理器做项目间 link 的情况下于独立项目中试用变更的有效方式。创建 canary 必须由核心团队或任何拥有管理员权限的人手动触发 publish 工作流并传入 PR 号。在为贡献者创建 canary 发布之前核心团队成员必须确认被发布的代码不是恶意的。通过 GitHub UI 创建打开 publish 工作流的运行界面右上角点击 Run workflowbranch 选项始终选择next无论 PR 在哪个分支上PR 号输入数字不带前导 #。通过 CLI 创建——把PR_NUMBER替换为实际 PR 号gh workflow run --repo storybookjs/storybook publish.yml --field prPR_NUMBER对照 publish.yml 的publish-canaryjob它会先校验触发者是 adminFail if triggering actor is not administrator然后检出该 PR 的 HEAD commit执行yarn release:version --exact 0.0.0-pr-$PR_NUMBER-sha-$SHORT_SHA设置精确版本再以yarn release:publish --tag canary发布。发布成功后会更新 PR 描述中的 Canary release 区块说明版本如何试用例如npx storybookversion sandbox失败则会在 PR 上留言并 触发者。canary 版本号格式为0.0.0-pr-PR_NUMBER-sha-COMMIT_SHA例如0.0.0-pr-23508-5ec8c1c3。使用 v0.0.0 是为了确保用户在使用允许预发布的 semver 范围如^7.2.0-alpha.0时不会意外装到 canary。注意所有 canary 发布都使用同一个 canary dist tag技术上可以用npm install storybook/clicanary安装但没有意义——后续 PR 的发布会迅速覆盖该 tag。因此应当始终安装具体版本字符串如npm install storybook/cli0.0.0-pr-23508-sha-5ec8c1c3。为什么不做更聪明的自动 canary官方文档给出的理由对所有PR 自动发 canary 是不安全的任何拥有 Write 权限的贡献者200 用户都可以提交恶意 PR 篡改发布脚本例如发布带挖矿脚本的 patch 版本。为此只有受保护分支next、main等上的工作流可以访问持有 npm token 的 Release 环境要求 admin 审批工作流运行也不行这会给核心团队发大量审批通知哪怕是核心成员自己触发的按标签或评论触发也不行工作流无法按标签/评论内容过滤触发只能在每次打标签/评论时触发再取消低效。6.2 FAQ何时使用 patch:yes 标签不是所有 PR 都需要回填到稳定版所以只有带patch:yes标签的才会被挑选。判断标准补丁只针对重要且时效性强的修复不适合小改进或全新 feature大幅改变代码架构的 PR 理想情况下也不该打回因为会提高未来合并冲突的概率拿不准时问核心团队。6.3 哪些变更算作可发布一组特定标签定义了 PR 变更的类型及是否可发布releasable。可发布变更会出现在 changelog 并触发版本升级不可发布变更不会。这份标签清单硬编码在 get-changes.ts 中export const RELEASED_LABELS { BREAKING CHANGE: ❗ Breaking Change, feature request: ✨ Feature Request, bug: Bug, maintenance: Maintenance, dependencies: Dependencies, } as const; export const UNRELEASED_LABELS { documentation: Documentation, build: ️ Build, unknown: ❔ Missing Label, } as const;即可发布标签为BREAKING CHANGE、Feature request、Bug、Maintenance、Dependencies不可发布标签为Documentation、Build。PR 在发布时若没有上述任何标签也被视为不可发布。文档类变更不进 npm 包、不改变行为build 类变更测试、CI 等纯属内部实现。为什么没有 Release PR 被准备 通常就是因为next上只有不可发布变更准备工作流自我取消了——不升版本、不写 changelog 的发布没有意义。可以在两个 prepare 工作流的运行历史中查看它们是否被 cancel。6.4 如何修改发布工具/流程整个流程基于 .github/workflows/ 下的 GitHub Actions 工作流与 scripts/release/ 脚本懂行的维护者可以直接修改。简答如何改——把它当作一个普通 PR 来做并且把该改动也 patch 回main。更详细的说明脚本分别从main或next运行所以修改发布脚本时必须把它 patch 回main才能对 patch 发布生效若需立即生效还要手动 cherry-pick 到main。工作流文件通常从next运行但为一致性也建议 patch 回main而 publish 工作流运行在latest-release和next-release上因此改动必须patch 回去。6.5 为什么改完标题/标签后要重新触发工作流因为工作流只在next的 push 上触发PR 元数据变化标题、标签、revert不会触发它。所以改过任何 PR 后必须手动重新触发以重新生成 changelog 与版本升级。你也可以手动改 changelog但那意味着 PR 及其标题/标签不再是唯一事实来源。6.6 输入与版本升级的对应关系每个版本场景及其触发输入都在 3.1 节 的表格中描述version.test.ts 的参数化用例则给出了每种输入组合对应的精确输出是判断哪个输入产生哪个版本的最终依据。7. 为什么需要独立的发布分支更简单的分支方案是把版本分支直接合并回main/next然后在该分支上直接触发发布Changesets 等工具就是这么做的。问题在于你可能发布掉一部分不属于准备好的 Release PR 的变更——它们既没经过 QA也不在 changelog 里。例如Releaser 正用冻结分支做发布QA 期间另一位成员把 some-simultaneous-bugfix 合入了next如果在 tagv7.1.0-alpha.29的最后提交上发布发出去的是那一刻的全部内容所有方点包括 QA 途中合入的 whoops! bugfix——而它从未属于这个 Release PRPR 是在 bugfix 合并前准备的。相反从next-release发布再合并回next该 bugfix 就不会进入本次发布而是进入下一次这背后的原理是未发布变更的判定方式是——列出HEAD历史中的所有 commit减去最新版本 tag 历史中的 commit。由于 bugfix 不在上一个版本的历史中它会被计入下一次发布的变更列表从而自然进入v7.1.0-alpha.30。8. 小结Storybook 的发布体系可以用一句话概括next/main 承载开发next-release/latest-release 承载发布Release PR 是人与自动化之间的契约。其设计亮点在于用可再生成的 Release PRforce push 覆盖 freeze 标签保护保证 changelog 与 PR 元数据始终同步GitHub 是唯一事实来源用延迟版本升级deferredNextVersion把准备与发布两个阶段解耦准备工作流不触碰各包版本publish 工作流合并后才真正 bump 并发包用标签体系patch:yes / freeze / ci:daily / patch:done 与可发布标签驱动整个自动化决策用发布分支间接层杜绝发布内容与 QA 内容不一致的竞态保留本地手动发布与canary两条逃生通道兼顾紧急修复与开发中的快速试用。相关实现与文档入口发布规范、发布脚本集、prepare-non-patch-release.yml、prepare-patch-release.yml、publish.yml。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

最新新闻

日新闻

周新闻

月新闻