首页
/ Cypress 稳定版发布全流程指南:从 develop 分支到 npm dist-tag 的工程化落地手册

Cypress 稳定版发布全流程指南:从 develop 分支到 npm dist-tag 的工程化落地手册

2026-09-07 21:14:55作者:裘旻烁

在 Cypress 这个仓库中,"发布"特指将 Cypress 桌面端二进制(binary)cypress npm 模块从一个"开发中"状态正式变为用户可下载、可 npm install 的稳定版本。本指南完整梳理这一发布流程:从权限与凭据准备、CI 上的预发布验证,到本地执行的 24 步发布操作(制作稳定制品、打 dev/latest dist-tag、更新下载服务器 manifest、发版打 tag、回填 issue 评论等)。读完本文,你将掌握该仓库的发布骨架(见 guides/release-process.md),并理解每一步背后对应的脚本实现与设计动机。

本文聚焦的主流程针对 Cypress binary + cypress npm 模块;仓库中位于 npm/ 目录下、以 @cypress/ 为命名空间的其余 npm 包不在此流程内——它们在合并进 develop 后由 semantic-release 自动发布(详见 CONTRIBUTING.md 的 releases 一节)。

谁可以执行发布

任何开发者都可以在本地构建二进制与 npm 包(见 构建发布制品指南),但只有 cypress npm 组织的成员才能把 Cypress 应用部署到 CDN、并把 cypress 模块发布到 npm registry。发布脚本假设执行人同时具备两类基础设施权限:可读写 AWS S3(即 Cypress CDN)的 AWS 账户,以及可发布 cypress 包的 npm 账户权限。

发布前置条件

发布是一系列人工驱动、半自动化的命令组合,执行前必须完成权限、凭据与代码仓库三层准备。

1. AWS SSO 与 prod profile

发布脚本需要把二进制推入 Cypress CDN(S3 bucket cdn.cypress.io),因此要求配置一个 AWS SSO profile,角色为 Team-CypressApp-Prod(在 "App Developer" 分栏中可找到若干必要的配置值)。脚本假定该 profile 名为 prod。AWS 配置文件最终应形如:

[profile prod]
sso_start_url = <start_url>
sso_region = <region>
sso_account_id = <account_id>
sso_role_name = <role_name>
region = <region>
cli_pager = <pager>

若你的凭据放在其他 profile 名下,则必须在后续步骤中通过 AWS_PROFILE 环境变量显式指定(例如 export AWS_PROFILE=production)。

2. 环境变量

发布过程中多个阶段需要注入凭据,可事先在 1Password 中获取:

  • release-automations 阶段需要的 GitHub 凭据:
GITHUB_TOKEN="..."
GITHUB_APP_CYPRESS_INSTALLATION_ID=
GITHUB_APP_ID=
GITHUB_PRIVATE_KEY=

其中 cypress-bot GitHub App 凭据用于以机器人身份在 issue 上回填"已修复版本"评论。

  • 清空 Cloudflare 缓存所需凭据(供第 6 步的 prepare-release-artifacts 与第 14 步的 binary-release 使用):
CF_ZONEID="..."
CF_TOKEN="..."

没有 1Password 访问权限时,应找一位执行过部署的团队成员协助。

3. 待贡献的关联仓库

发布过程会向以下仓库发起 PR 或运行其中的命令,需提前在本地检出并准备好:

  • cypress-realworld-app(典型用户消费形态的示例工程)
  • cypress-documentation(发布版本文档与 changelog)
  • cypress-docker-images(Docker 镜像)
  • cypress-io/release-automations(批量 issue 评论工具)

4. 发布前:CI 全量验证

正式发布前,develop 分支必须已经由 CI 完成跨平台构建与真实项目回归。对 develop 的每次提交,CI 会自动执行以下工作:

  1. 下一个目标版本号内建到 npm 包中进行构建;
  2. 在 CircleCI 上构建 Linux、Mac 与 Windows 三平台的二进制;
  3. 将二进制与新 npm 包上传到 AWS S3 bucket cdn.cypress.io 下的 beta 目录;
  4. 使用新上传的包与二进制启动各测试项目,而不是从 npm registry 安装,从而在真实项目上回归本次改动。

每个目标操作系统都会启动多个测试项目,结果以 GitHub 状态检查(status checks)回传,用来判断改动是否破坏了 Cypress 的真实使用场景。若第 4 步的发布操作被执行,务必先确认 develop 上的状态检查全部通过(即存在一个绿色的 CI 基线)。

版本号如何确定

"X.Y.Z"在整份发布流程中指代 Cypress 的下一个目标版本号,其确定逻辑独立封装在 scripts/get-next-version.js,说明文档见 guides/next-version.md

该脚本按以下优先级决策:

  1. 若存在环境变量 NEXT_VERSION(如 NEXT_VERSION=1.2.3),直接输出该值并退出。发布分支或强制指定某个主版本号时通常会这么做。
  2. 否则分析当前分支自上次发布以来的提交,依据语义化提交信息推算版本:
    • 只统计触及 packages/*cli/* 的提交,避免 npm/ 子包的提交误触发 CLI/binary 版本递增;
    • 采用 angular 提交风格:fix: 触发 patch 递增,feat: 触发 minor 递增,带 BREAKING CHANGE: footer 的提交触发 major 递增(实现上通过 conventional-recommended-bumppackagescli 两个路径分别计算并取 semver 较大者);
    • package.json 中硬编码的真实版本会优先于推算结果被采用,而 0.0.0-development 哨兵版本则会被忽略。

可用 node ./scripts/get-next-version.js 在本地调试,它会分析当前分支的提交并打印推算结果。

发布新版本的标准操作步骤

下面的 "X.Y.Z" 即上文所述的下一版本号。动身前建议先通知团队:develop 分支在发布期间将被锁定

步骤 1:安装并测试预发布版本

目标版本在 CI 上构建出的是"预发布(pre-release)"产物,先在本地人工验证其可用性:

  • 安装新版本:
    • 全局安装:npm install -g <cypress.tgz 路径>
    • 或在项目内安装:npm i -D cypress@file:<cypress.tgz 路径>
  • 快速冒烟测试:执行 cypress open,进入一个项目跑一条测试,确认一切正常;
  • 可选:将新版本安装进既有成熟项目(cypress-realworld-app 使用 yarn,是典型消费端形态)后运行测试;
  • 可选:进行更彻底的测试,例如拿新版本对 Cypress Cloud 仓库跑回归。

步骤 2:确认 on.cypress.io 链接清单已部署

确保所有对 on.cypress.io 链接清单(links manifest)的改动都已合入 develop 并完成部署,否则新版本中相关跳转链接可能失效。

步骤 3:(可选)创建 Release PR

如果本轮有新增的配套发布物,提交一个用于"升版本 + 记 changelog"的 Release PR:

  • 若有新的 cypress-example-kitchensink 版本,则升级 packages/example 的依赖并运行 yarn 以保持 lockfile 最新;
  • 编写 Cypress Changelog 指南中的 release 小节更新 cli/CHANGELOG.md
  • 若无需改动 changelog、也没有新的 kitchensink 版本,本步可跳过,直接沿用 develop 上最后一次构建产物。

步骤 4:等待绿色基线并核对预发布版本注释

develop 分支 CI 全绿,且确认 cypress-bot 已在提交上以注释形式给出 darwin-x64darwin-arm64linux-x64linux-arm64win32-x64 五个平台/架构的预发布版本地址后,才可进入发布。让 CI 变绿的实用技巧:

  • windows 工作流若因超时报错,可仅从最后一个失败步骤重试;
  • windows 工作流偶发在多次尝试间卡死在失败态,此时整体重启一次该工作流通常能恢复;
  • linux-x64 工作流若因 flaky 测试失败但 Percy 已 finalize 构建,必须从失败步骤重启;整体重启会触发 Percy 在下一次报 "Build has already been finalized" 错误,届时只能靠推送新提交重来。

步骤 5:登录 AWS SSO

aws sso login --profile <profile_name>

若你的 profile 不叫 prod,需 export AWS_PROFILE=production(以实际名字为准),让后续步骤使用正确的身份。

步骤 6:运行 prepare-release-artifacts 制作稳定制品(仅 Mac/Linux)

这是把"最新提交"升级为"稳定发布"的核心一步,由 scripts/prepare-release-artifacts.js 驱动:

yarn prepare-release-artifacts --sha <commit sha> --version <new target version>

脚本执行前先做参数校验:--sha 必须是 40 位十六进制 commit SHA,--version 必须是 X.Y.Z 形式的语义版本号(见 prepare-release-artifacts.js)。运行后依次发生:

  • 通过 node ./scripts/binary.js move-binaries --sha ... --version ...,把对应 commit SHA 的二进制从 S3 的 beta 目录移动到 desktop/<新版本> 目录;
  • 清空该版本的 Cloudflare 缓存;
  • 把预发布的 cypress.tgz 转换成可直接发布的稳定 npm 包。

move-binaries 的底层实现在 scripts/binary/move-binaries.ts:它会列出 S3 上匹配该 commit 的构建路径(格式如 beta/binary/3.3.0/darwin-x64/circle-develop-<40位sha>-<build号>/),当同一 commit 对应多条路径时选取 build 号最大(最后构建)的那条,经交互确认后移动到统一的稳定目录。

yarn prepare-release-artifacts --dry-run 可预览脚本将要执行的命令而不真正执行(prepare-release-artifacts.js)。另外,在 macOS 上执行需要加前缀 COPYFILE_DISABLE=1,避免 OSX 把隐藏文件打进了二进制的 .tgz 包。

步骤 7:校验 npm 登录状态

npm whoami

未登录则执行 npm login。若你还不是 Cypress 包的 maintainer,需请团队成员把你加入组织。

步骤 8:以 dev tag 发布生成好的 npm 包

用 npm service account 发布第 6 步产出的稳定 tgz,但 tag 仍是 dev

npm publish /tmp/cypress-prod.tgz --tag dev

/tmp/cypress-prod.tgz 正是 scripts/create-stable-npm-package.sh 的产物:它从 https://cdn.cypress.io/beta/npm/<版本>/linux-x64/develop-<sha>/cypress.tgz(仅支持 linux-x64 的 tgz,见 prepare-release-artifacts.js)下载预发布包,解压后把 package/package.json 中的 buildInfo.stable 改写为 true,再重新打包——这一步完成"预发布包 → 稳定包"的标记切换。

步骤 9:复核 dist-tags

确认新版本已挂在 dev tag 下,且 latest 仍指向上一稳定版本:

npm view cypress dist-tags

示例输出(注意 latest 保持不变):

$ npm view cypress dist-tags
{ latest: '14.5.3', dev: '14.5.4' }

npm view 反映最新版本信息可能存在数分钟延迟,属于正常现象。

步骤 10:验证 cypress@X.Y.Z

在真实使用形态下再验证一次刚发布的版本:npm install -g cypress@X.Y.Z,随后 cypress open 进入项目跑冒烟测试;建议再安装进 cypress-realworld-app 等既有项目执行测试,必要时进行更深入的回归。

步骤 11:处理版本文档与 changelog PR

cypress-documentation 中审查本版本的文档与 changelog PR,若没有则创建一个:

  • 把 Release PR 中的本版本 changelog 内容复制进 /docs/app/references/changelog.mdx,并把其中的 docs.cypress.io 链接调整为 host-relative 路径;
  • 在版本标题下按 _Released MMM DD, YYYY_ 格式补上发布日期;
  • 把发布相关的文档改动合入主 Release PR。

步骤 12:创建新版 Docker 镜像

cypress-docker-images 中为 factory/.env 的 cypress 版本发起 PR 升级到新版本,并在镜像测试通过后再继续。

步骤 13:将 latest tag 指向新版本

npm dist-tag add cypress@X.Y.Z

执行后 npm view cypress dist-tags 应显示 latestdev 均为新版本。

步骤 14:运行 binary-release 更新下载服务器 manifest

yarn binary-release --version X.Y.Z

该命令对应 node ./scripts/binary.js release(见 package.json 中 scripts 定义),其实现位于 scripts/binary/index.js。它会更新下载服务器的 manifest(download.cypress.io/desktop.json),并确保该版本二进制在每个系统都可用:release 完成后自动对 darwin-x64darwin-arm64linux-x64linux-arm64win32-x64 五个组合逐一发起 download.cypress.io/desktop/<version>?platform=...&arch=... 的探测请求校验可下载性,同时读取 manifest 校验其中 version 字段与目标版本一致。若某个平台探测失败,脚本会提示先执行 yarn binary-purge --version X.Y.Z 清理 Cloudflare 缓存,再用 yarn binary-ensure --version X.Y.Z 复检。

步骤 15:合入文档与 Docker 镜像 PR

合并第 11 步的文档 PR 与第 12 步的 docker 镜像 PR,Docker 镜像随之发布。

步骤 16:(如需)部署 kitchensink 示例站点

当需要把新版 cypress-example-kitchensink 部署到 example.cypress.io 时,按 packages/example/README.md 的 Deployment 章节操作:

yarn workspace @packages/example build

先检查 ./packages/example/build 内容是否正确,再执行:

yarn workspace @packages/example deploy

该命令把 cypress-example-kitchensink 的改动作为一个 commit 合入 gh-pages 分支,由其自身 CI 部署上线;最后访问部署站点确认变更生效。

步骤 17:基于版本提交创建 Git tag

从发布了版本号递增的那个 commit 上打 tag:

git checkout develop
git pull origin develop
git log --pretty=oneline
# 复制版本递增 commit 的 sha
git tag -a vX.Y.Z -m vX.Y.Z <sha>
git push origin vX.Y.Z

步骤 18:创建 GitHub Release

在 GitHub Releases 页面选择刚推送的 tag,补上与历史 Release 风格一致的发布说明。

步骤 19:给已修复 issue 批量评论

verify-release-readiness CircleCI job 下载 releaseData.json 构件,然后在 cypress-io/release-automations 仓库内执行:

npm run do:comment -- --release-data <path_to_releaseData.json>

cypress-bot 会据此向每个"本次发布已修复"的 issue 追加版本评论(这也解释了前置条件中为何需要 GitHub App 凭据)。

步骤 20:确认无遗留的 stage: pending release issue

检查已关闭 issue 中是否还有带 stage: pending release 标签的残留,确保本轮修复都被正确标记。

步骤 21:通知团队重新开放 develop

发布公告由 GitHub bot 自动发送到 releases 频道;如需补充细节,以回复形式追加即可。

步骤 22:清理 changelog 校验开关

若本轮使用了 SKIP_RELEASE_CHANGELOG_VALIDATION_FOR_BRANCHES 变量绕过 changelog 校验,请按需调整其值或从 CircleCI 中删除,确保后续 PR 恢复常规校验。

步骤 23:回填各测试/示例仓库的依赖版本

检查各 cypress-test-*cypress-example-* 仓库:若存在用于回归本版本的 x.y.z 分支,将其 package.json 中的 cypress 依赖更新为新发布版本并合入主干;无对应分支的项目可在 Renovate 依赖 issue 中勾选 Update dependency cypress to X.Y.Z 让其自动建 PR,通过后合入。至少应更新 cypress-realworld-appcypress-example-recipes 两个项目。

步骤 24:轮换 npm 凭据

在 CircleCI 的 org-npm-credentials context 内轮换 NPM_TOKEN;若登录时新建过 npm token,请一并删除该临时 token。

至此发布完成。

把发布流程放在一起看:制品仓库与 CDN 布局

把上述步骤串联起来,就能理解 Cypress 发布的制品流动规律:

  • npm 包(.tgzcli 构建(命令行工具、类型定义与 Module API),以 cypress 包名安装进用户项目的 node_modules
  • 二进制(.zippackages 目录构建(Electron 应用、ffmpeg 及各子包成品),在安装 cli 或执行 cypress install 时被拉取到系统缓存;
  • CI 期间所有产物先落在 S3 的 beta 路径下,例如 beta/binary/<版本>/<平台>/<develop-sha>/cypress.zipbeta/npm/<版本>/develop-<sha>/cypress.tgz(路径拼装逻辑见 scripts/binary/upload-build-artifact.js);
  • 第 6 步 move-binaries 把它们迁入 desktop/<版本>/releaseFolder: 'desktop' 定义于 scripts/binary/util/upload.js),第 14 步 binary-release 再保证下载 manifest 与各平台 URL 生效,整个发布链路即告闭环。

需要了解制品如何在本地构建(对应"Anyone can build"部分)时,可阅读构建发布制品指南;相关的自动化单元测试(如 move-binaries、制品准备与上传逻辑)可在 snapshots 目录对应的快照测试中继续追溯。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.15 K
2.78 K
kernelkernel
deepin linux kernel
C
34
18
docsdocs
暂无描述
Markdown
904
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
931
1.86 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
862
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.95 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.38 K
1.47 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
535
605
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
549
398
leetcodeleetcode
🔥LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解
Markdown
77
23