Polaris React 仓库发布全流程指南:Snapshot 快照、Changesets 版本发布与 Style Guide 部署

原创2026-10-06 09:35:541,460 阅读
文章标签:前端UI组件

Polaris React 仓库发布全流程指南:Snapshot 快照、Changesets 版本发布与 Style Guide 部署

本文以 Polaris React 仓库的 Releasing 文档 为核心,系统讲解该 monorepo 的两条发布主线:面向「测试中的功能分支」的 Snapshot 快照发布(/snapit 命令),以及面向正式版本的 Changesets 版本发布(含 beta 预发布分支);同时覆盖 polaris-for-vscode 扩展与 polaris.shopify.com 风格指南站点的自动部署机制。读完本文,你将掌握从"提交一个 changeset"到"把新版本发布到 npm、并完成下游 Shopify/web 升级"的完整链路,以及如何在发布前用快照包在真实项目中做验证(tophatting)。

一、发布体系总览

Polaris 是一个由 npm 包、VS Code 扩展和站点组成的 monorepo,其根目录 package.json 中以 pnpm + turbo 管理全部工作区。整个发布体系可以归纳为三条自动化流水线:

流水线 触发方式 产物 对应工作流
Snapshot 发布 PR 评论 /snapit 0.0.0-snapshot-release-<时间戳> 形式的临时 npm 包 .github/workflows/snapit.yml
正式版本发布 main / next 分支 push 常规 semver 版本(含 beta dist tag) .github/workflows/release.yml
VS Code 扩展发布 polaris-for-vscode CHANGELOG 变更 Visual Studio Marketplace 扩展 .github/workflows/release-vscode.yml
风格指南站点部署 polaris.shopify.com/** 合入 main polaris.shopify.com 站点 .github/workflows/deploy-polaris.shopify.com.yml

三条流水线共享同一套前置设施:changeset 变更集 是版本发布的"货币",任何需要版本 bump 的改动都必须先通过 pnpm changeset 记录。下文先从最轻量的 Snapshot 发布讲起。

二、Snapshot 快照发布:无需发版即可在消费方项目中验证改动

2.1 什么是 Snapshot 发布

Snapshot release 是一种在不发布新正式版本的前提下,把分支上的改动打包发布到 npm、供消费方项目安装验证的机制。它非常适合发布前的 tophat 验证:例如在发布新 @shopify/polaris 版本前,先在 Shopify/web 的升级分支里安装快照包,确认 UI 表现符合预期。

从仓库文档与源码看,发起 Snapshot 需要满足两个前提条件:

  1. CI 在功能分支上通过——保证快照包构建自一个可用的代码状态;
  2. 功能分支上至少有一个待处理的 changeset——changeset 用于声明哪些包需要被打包进快照(对应 CONTRIBUTING.md 的 adding-a-changeset 章节)。

2.2 使用方法:/snapit 斜杠命令

在满足上述条件的功能分支 PR 中,直接添加一条评论:

/snapit

其后的执行链路由 .github/workflows/snapit.yml 驱动,该工作流监听 issue_comment 的 created 事件,核心步骤是:

- name: Create snapshot
  uses: Shopify/snapit@v0.0.14
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
  with:
    build_script: pnpm build:release

可以看到,SnapIt action 会先执行根目录脚本 pnpm build:release(即 turbo run build --filter='!polaris.shopify.com',构建除站点外的全部包),再基于当前 PR 的 changeset 生成快照版本并发布到 npm。整个流程中:

  • github-actions bot 会在工作流开始运行时对你的评论回复 👀;
  • 构建完成后回复 🚀,并贴出下一次正式版本发布中会包含的每个 npm 包的快照安装命令(如 pnpm add @shopify/polaris@0.0.0-snapshot-release-20220525184558,该格式示例见 CONTRIBUTING.md 的 Testing 章节)。

快照版本号通常形如 0.0.0-snapshot-release-<时间戳>,与正式 semver 完全隔离,不会污染正式版本序列。

2.3 polaris-for-vscode 的快照

polaris-for-vscode 扩展本身发布到 Visual Studio Marketplace,它的发布不依赖 /snapit,而是由 .github/workflows/release-vscode.yml 在 polaris-for-vscode/CHANGELOG.md 或 polaris-tokens/CHANGELOG.md 发生变更并合入 main 时自动触发:

on:
  push:
    paths:
      - 'polaris-for-vscode/CHANGELOG.md'
      - 'polaris-tokens/CHANGELOG.md'
    branches:
      - main

工作流依次执行 pnpm install --frozen-lockfile、pnpm build --filter=polaris-for-vscode 构建扩展,最后以 pnpm --filter=polaris-for-vscode vsce publish 配合 VSCE_PAT 密钥发布到 Marketplace。这意味着:只要在发布流程中为扩展生成了 CHANGELOG 条目,其发布就是全自动的,无需人工干预。

三、Version Releases:基于 Changesets 的正式版本发布

3.1 Changesets 机制与 GitHub Action 的职责

Polaris 使用 Changesets 处理仓库内各包的版本发布。整体编排由官方 changesets/action 完成,其职责在 Releasing 文档 中被明确为四件事:

  1. 创建 changeset-release/main 分支,并打开一个标题为 "[Version Packages]" 的 PR,该 PR 始终保持 changeset version 的一次最新运行结果;
  2. 每当有 PR 合入 main,就把 changeset-release/main 分支更新到最新;
  3. 当 changeset-release/main 分支合入 main 时执行正式发布;
  4. 发布完成后重建 changeset-release/main 分支,并再次打开新的 "[Version Packages]" PR,为下一轮发布做准备。

这个"发布即重建"的设计保证了 main 分支随时处于可发布状态——每次发布结束,新的版本 PR 已经就位,只等下一批 changeset 积累。

3.2 工作流源码佐证:release.yml 与根脚本

正式发布由 .github/workflows/release.yml 承载。其关键配置如下:

on:
  push:
    branches:
      - main
  workflow_dispatch:
    inputs:
      branch:
        description: 'Branch to release from'
        required: true
        default: 'main'

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
      id-token: write
    steps:
      # ... checkout / pnpm 安装 / 构建 ...
      - name: Build
        run: pnpm build:release
      - name: Create release Pull Request or publish to NPM
        id: changesets
        uses: changesets/action@v1.5.3
        with:
          version: pnpm version-packages
          publish: pnpm release-packages
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_CONFIG_PROVENANCE: true

该工作流把两个关键命令委托给根 package.json 中的脚本:

脚本 实际执行内容 作用
version-packages changeset version && pnpm install --lockfile-only 依据 changeset 提升各包版本号、生成 CHANGELOG,并同步 lockfile
release-packages pnpm build:release && changeset publish 重新构建全部发布包后,将新版本发布到 npm

其中 NPM_CONFIG_PROVENANCE: true 启用了 npm 的 provenance 签名(配合 id-token: write 权限),用于在 npm 上记录包的构建来源;workflow_dispatch 输入项 branch 允许手动指定从哪个分支发起发布,默认 main。

另外,.changeset/config.json 中的关键配置也值得关注:

{
  "changelog": ["@changesets/changelog-github", {"repo": "Shopify/polaris"}],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
    "updateInternalDependents": "always"
  }
}
  • access: public:包以公共可见方式发布到 npm;
  • changelog 使用 @changesets/changelog-github,自动把 PR 链接与贡献者写进 CHANGELOG;
  • updateInternalDependents: always:仓库内部包相互依赖时,发布后依赖方也总会得到更新,避免出现"新包配旧依赖"的版本错位。

3.3 创建 changeset:版本发布的起点

任何需要发布的功能分支都必须携带 changeset。在 .changeset/README.md 中给出了交互式创建流程,从功能分支运行:

pnpm changeset

依次回答 CLI 的三个问题:

  1. 🦋 Which packages would you like to include?——用 Space 键选中发生变更的包,Enter 进入下一题;
  2. 🦋 Which packages should have a major bump?——如有破坏性变更则用方向键与 Space 选中这些包,否则直接 Enter;
  3. 🦋 Which packages should have a minor bump?——同理选择 minor 包,不选择则默认按 patch 处理。

最后为这次变更填写 changelog 摘要。写 changelog 时遵循 CONTRIBUTING.md 的写作建议:使用积极、对话式的语气,避免冗余,使用 sentence case 与平实的语言;polaris.shopify.com、开发依赖升级、基础设施类 chore 通常可以省略。

仓库还在 CI 层面强制校验 changeset:.github/workflows/changelog.yml 会在每个 PR 上执行 npx @changesets/cli status --since="origin/main",只要 PR 中缺少 changeset 就会检查失败(dependabot 机器人、changeset-release 分支以及带有 🤖Skip Changelog 标签的 PR 除外)。

3.4 语义化版本:什么改动 bump 什么版本

CONTRIBUTING.md 的 Semantic versioning 章节 明确了 Polaris 包的版本规则,发布与 changeset 的 bump 选择均以此为准:

  • Major(破坏性):移除组件、移除组件 prop、改变 prop 接受的类型、对依赖最低版本做破坏性升级、对公开 Sass 变量/函数/mixin 做破坏性变更;
  • Minor(新功能):新增组件、新增 prop、prop 增加可接受类型、对组件/公开 Sass API 引入弃用警告(为下一个 major 版本铺路);
  • Patch(修复):改变组件生成的 HTML(含类名增删改)这类表面变更、不触及公开 API 的改动、非破坏性的依赖最低版本升级、私有 Sass API 的破坏性变更。

这也是为什么破坏性改动应当走 next 分支、而 main 分支只接受非破坏性改动(详见 CONTRIBUTING.md 的 Breaking changes 章节)。

四、Prerelease(beta):为下一个大版本准备的预发布分支

正式发布之外,Polaris 通过 next 分支承载下一个大版本的预发布(prerelease)。机制上与常规 Changesets 发布一致:合并到 next 分支的含 changeset 的工作,会自动生成标题为 "[Version Packages (beta)]" 的预发布 PR,其中包含将进入下一个大版本的全部改动;将该 PR 合入 next 后,会以 beta dist tag 创建一个新的预发布版本。

如果当前仓库中还不存在 next 分支,按如下步骤建立预发布分支(源自 Releasing 文档 的 Prerelease 章节):

  1. 创建新的 next 分支用于预发布开发;

  2. 运行 pnpm changeset pre enter beta,让 changeset 进入 beta 预发布模式;

  3. 调整发布工作流 .github/workflows/release.yml,使其同时监听 main 与 next 两个分支:

    on:
      push:
        branches:
          - main
          - next
    
  4. 后续功能开发从 next 分支拉取分支进行;

  5. 在 next 分支上正常创建 changeset 并合并;

  6. 此时发布 PR 就会自动为预发布分支生成,预发布流水线即告就绪。

值得注意的细节:正式发布的 release.yml 默认只监听 main;预发布流程要求你手动把 next 加进 on.push.branches 列表,这正是文档示例中给出的配置片段。而 pnpm changeset pre enter beta 会在 .changeset 目录中写入预发布状态文件,使后续合并的 changeset 统一按 beta 预发布处理。

五、执行一次正式版本发布的完整步骤

5.1 谁可以发布

按仓库文档说明,任何 Shopify 成员都可以执行版本发布;需要支持时可联系 GitHub 上的 @Shopify/polaris-team 或 Slack 频道 #polaris 中的 @polaris-developers 团队。

5.2 步骤 1:🧪 测试 "[Version Packages]" PR

正式发布前的第一道闸门是用快照验证待发布内容:

  1. 对当前打开的 "Version Packages]" PR 创建一次 [Snapshot 发布(即在其中评论 /snapit,前提是该 PR 已包含至少一个 changeset);
  2. 在 Shopify/web 的 Spinstance 中新建分支,将 @shopify/polaris 升级到对应的快照版本(形如 pnpm add @shopify/polaris@0.0.0-snapshot-release-<时间戳>),用于人工 tophat 验证。

这一步把"即将发布的代码"与"正式发布"解耦:快照包验证通过后,才进入正式发布环节。

5.3 步骤 2:🚢 发布新版本

  • 确认 Shopify/web 升级分支 CI 通过后,批准并合并 "[Version Packages]" PR;
  • 合并动作会触发 release.yml 工作流,执行 changeset publish 把各包发布到 npm。

5.4 步骤 3:🕸️ 在 Shopify/web 中升级 @shopify/polaris

为 Shopify/web 的升级分支起草 PR,PR 中需要包含:

  • "[Version Packages]" PR 的链接;
  • 需要 tophat 的关键事项的简要说明(Tl;dr);
  • Spinstance URL;
  • Key dependencies 与 Polaris 两个标签;
  • 将 "[Version Packages]" PR 描述中列出的贡献者添加为 reviewers。

随后,等新版本在 npm 上可用后,在 Shopify/web 升级 PR 中安装新版本 @shopify/polaris;最后把升级 PR 链接发到群 Slack DM,请贡献者在 Spinstance 中 tophat 各自的改动、标记回归问题或直接批准 PR。

5.5 步骤 4:🚀 升级 Shopify/shopify-frontend-template-react

在 Shopify/web 升级确认无误后,同步把 @shopify/polaris 升级到 shopify-frontend-template-react 模板仓库,保证新建的 Shopify 应用开箱即可使用最新版 Polaris。

5.6 步骤 5 与 6:🦄 致谢贡献者并公告

  • 为本次发布的贡献者送出 Unicorn(内部致谢文化);
  • 在 #polaris Slack 频道以及 Workplace 的 Polaris Updates / Engineering 群组中公告新版本,并分享 Unicorn。

整个发布流程体现了"自动化产出、人工把关验证、全链路追踪"的工程实践:Changesets 负责自动生成版本与 CHANGELOG,Shopify/web 的升级验证把发布风险拦截在上游消费方。

六、Style Guide 自动部署

风格指南站点 polaris.shopify.com 采用"改动即部署"的策略:当 /polaris.shopify.com 目录下的新改动合入 main 分支时,站点会自动部署。

底层由 .github/workflows/deploy-polaris.shopify.com.yml 实现。该工作流监听 main 分支且路径过滤为 polaris.shopify.com/**,并在部署前用 GitHub Actions 的 workflow_dispatch API 调用另一个仓库 polaris-site-prod-kit 中的 build-and-deploy.yml 工作流:

on:
  push:
    branches:
      - main
    paths:
      - 'polaris.shopify.com/**'

# ...
script: |
  await github.rest.actions.createWorkflowDispatch({
    owner: "shopify",
    repo: "polaris-site-prod-kit",
    workflow_id: "build-and-deploy.yml",
    ref: "${{ inputs.branch || 'main' }}",
  });

即:本仓库负责"感知变更并下发指令",站点构建与上线则由独立的 polaris-site-prod-kit 仓库执行。这样的解耦让文档站点发布与 npm 包发布完全互不阻塞——修改 polaris.shopify.com 下的内容(如 content 目录 中的 MDX 文档、pages 目录 中的示例页面)不会触碰任何 npm 包版本。

七、常见问题与排查要点

  • /snapit 评论发出后没有反应? 检查功能分支 CI 是否通过、是否存在至少一个 pending changeset(changelog.yml 的 CI 检查会直接给出缺失提示);SnapIt action 需要仓库配置 NPM_TOKEN 与 GITHUB_TOKEN 密钥。
  • 快照包安装后不是最新代码? 快照基于 PR 当前 head 构建,推送新提交后需重新评论 /snapit 生成新快照(参考 CONTRIBUTING.md 的 Testing 章节)。
  • 发布后 npm 上找不到新版本? 确认 "[Version Packages]" PR 已合入 main,且 release.yml 中的 NPM_TOKEN 有效;若从 next 分支发布,还需确认该分支已加入工作流的 branches 列表且执行过 pnpm changeset pre enter beta。
  • 破坏了 CHANGELOG 检查? 任何改动包版本的 PR 都要运行 pnpm changeset 并遵循 changelog 写作规范;纯站点改动(polaris.shopify.com)可省略。

结语

从 pnpm changeset 记录一次变更,到 /snapit 生成可验证的快照,再到 Changesets 自动产出 "[Version Packages]" PR、合并即触发 npm 发布,最后在 Shopify/web 与模板仓库中完成下游升级——Polaris 的发布体系把"人类判断"集中在最有价值的两个节点:快照验证(tophat) 与 合并发布 PR,其余环节全部交给 release.yml、snapit.yml 等自动化工作流。这套基于 Changesets + GitHub Actions 的发布模式,配合语义化版本规则与 beta 预发布分支,为多包 monorepo 的持续发布提供了一套完整可复用的工程范式。

登录后查看全文
polaris-react-archive