codecamp

Electron 版本管理

详细查看我们的版本控制策略和实现。

从 2.0.0 版开始,Electron 遵循 SemVer 规范。以下命令将安装最新稳定版的 Electron:

 npm Yarn 
npm install --save-dev electron
yarn add --dev electron

现有项目更新到最新的稳定版本:

 npm Yarn 
npm install --save-dev electron@latest
yarn add --dev electron@latest

Versioning scheme

下面概述了我们的 1.x 策略的几个主要变化。每项更改都旨在满足开发人员/维护人员和应用程序开发人员的需求和优先级。

  1. 严格使用 SemVer 规范

  2. 引入符合 semver 的 -beta 标签
  3. 引入常规提交消息
  4. 明确定义的稳定分支
  5. main分支没有版本信息,只有稳定分支会包含版本信息。

我们将详细介绍 git 分支是如何工作的,npm 标记是如何工作的,开发人员应该看到什么,以及如何能够支持更改。

SemVer

下面是一个表格,明确地将变化的类型映射到它们对应的 SemVer 类别 (例如Major,Minor,Patch)。

Major 版本增量 Minor 版本增量 Patch 版本增量
Electron 突破性 API 变更 Electron 无突破性 API 变更 Electron bug 修复
Node.js 重大版本更新 Node.js 次要版本更新 Node.js patch 版本更新
Chromium 版本更新 修复相关的 chromium 补丁

有关详细信息,请参阅 语义版本控制 2.0.0 规范

请注意,大多数 Chromium 更新都将被认为是破坏性的。可以向后移植的修复程序可能会被挑选为补丁程序。

稳定分支

Stabilization 分支是与 main 并行运行的分支,仅接受与安全性或稳定性相关的精心挑选的提交。这些分支永远不会合并回主分支。


自 Electron 8 以来,稳定分支始终为 marjar 版本,并且根据以下模板 $MAJOR-x-y 例如: 8-x-y。 在此之前,我们使用 minor 版本行,并将它们命名为 $MAJOR-$MINOR-x 例如: 2-0-x.

我们允许同时存在多个稳定分支,每个支持的版本一个。


Electron 项目将不支持较旧的线路,但其他团队可以拥有所有权并自行向后移植稳定性和安全修复程序。我们不鼓励这样做,但是认识到它使得许多应用程序开发人员的生活更轻松。

测试版发布和 bug 修复

开发人员想知道哪个版本可以 安全 使用。 即使是简单的功能也会使应用程序变得复杂。 同时,锁定到一个固定的版本是很危险的,因为你忽略了自你的版本以来可能出现的安全补丁和错误修复。 我们的目标是在 package.json 中允许以下标准的 semver 范围:

  • 使用 ~ 2.0. 0 只接受您的 2.0.0 版本的稳定性或安全性相关的修复程序。
  • 使用 ^ 2.0. 0 可允许不破坏性的 合理稳定 功能以及安全性和 bug 修复。

第二点重要的是使用 ^ 的应用程序仍然能够期望合理的稳定性水平。 为了达到这个目的,SemVer允许使用一个 pre-release 标识 来表示一个特定的版本还不够 安全 或 稳定

无论你选择什么,你将定期不得不在 package.json 中打破版本,因为突破性变更是 Chromium 的一个常态。

过程如下:

  1. 所有新的主要和次要版本系列都以 beta.N 的 SemVer 预发布标签指示的 beta 系列开始,例如2.0.0-beta.1。在第一个测试版之后,后续的测试版必须满足以下所有条件:

    1. 更改是落后的 API 兼容 (允许废弃)
    2. 实现我们稳定的时间表的危险必须是低的。
  2. 如果允许更改需要在释放测试版之后进行,则使用并增加预放标签,例如2.0.0-beta.2
  3. 如果特定的beta版本通常被认为是稳定的,那么它将作为稳定版本被重新发布,只改变版本信息。例如.0。 例如 2.0.0-beta.1. 在第一个稳定之后,所有的变化都必须落后兼容的 bug 或安全修复。
  4. 如果未来错误修复或安全补丁一旦发布稳定,它们将被应用,并且 补丁 版本被增量 ,例如 2.0.1

特别地,上述步骤意味着:

  1. 在测试周期的第 3 周前允许非破坏性的 API 更改,即使这些变化有可能造成适度的副影响。
  2. 在 Beta 周期的大多数时间点,承认功能标记的更改不会改变现有代码路径是可以的。用户可以在他们的应用程序中明确启用这些标志。

  3. 在 Beta 周期的第 3 周之后承认任何类型的功能都是  没有很好的理由。

对于每个主要和次要的颠覆,你都应该像以下示例一样进行操作:

2.0.0-beta.1
2.0.0-beta.2
2.0.0-beta.3
2.0.0
2.0.1
2.0.2

图片中的生命周期示例:

  • 创建了一个包含最新功能集的新发布分支。它会被发布为 2.0.0-beta.1
  • 一个 bug 修复进入 master,可以向后移植到发布分支。补丁已应用,新的测试版发布为 2.0.0-beta.2。  
  • 测试版被认为是 一般稳定 的, 它在 2.0.0 下作为非 beta 版本再次被发布。
  • 之后有个 0day 漏洞被发现,然后对 master 采取了修复措施。我们将修复程序反向移植到 2-0-x 行并发布 2.0.1。

几个不同的 SemVer 范围将如何接收新版本的示例:


Backport request process

所有受支持的发布行都将接受外部拉取请求,以向后移植先前合并到主版本的修复程序,尽管对于某些较旧的受支持行,这可能视具体情况而定。所有围绕发布线向后移植的有争议的决定将由发布工作组作为议程项目在他们提出向后移植 PR 的那一周的每周会议上解决。

Feature flags

功能标志是 Chromium 的一种常见的做法, 在网络开发生态系统中得到了很好的确立。 在 Electron 环境中, 功能标志或 软分支 必须具有以下属性:

  • 是在运行时或生成时启用/禁用的。我们不支持请求作用域功能标志的概念
  • 它完全细分新的和旧的代码路径; 重构旧代码以允许新功能 违反 功能标志内容
  • 在合并功能后, 功能标志最终将被删除

语义化提交

所有拉取请求都必须遵守常规提交规范,总结如下:

  • 会导致 SemVer major 版本改变的提交必须以BREAKING CHANGE:开头。
  • 会导致 SemVer minor 版本改变的提交必须以 feat: 开头。
  • 会导致 SemVer patch 版本改变的提交必须以 fix: 开头。

electron/electron 存储库还强制执行 squash 合并,因此您只需要确保您的 pull request 具有正确的标题前缀。

Versioned main branch

  • 主分支将始终在其 package.json 中包含下一个主要版本 X.0.0-nightly.DATE。

  • 发布分支永远不会合并回主分支。

  • 发布分支 package.json 中包含正确的版本.
  • 一旦一个主要的发布分支被削减,main 必须被撞到下一个主要的(即 main 总是被版本化为下一个理论上的发布分支)。

Historical versioning (Electron 1.X)

小于 2.0 的 Electron 版本编号并不遵循 SemVer 规范: major 版本对应最终用户 API 的变更, minor 版本更新对应 Chromium 的主版本更新, patch 版本更新会带来新功能和 bug 修复。 虽然方便开发人员合并功能,但却为面向客户端应用程序的开发人员带来了麻烦。Slack、Teams、Skype、VS Code 和 GitHub Desktop 等主要应用程序的 QA 测试周期可能很长,稳定性是非常需要的结果。尝试吸收错误修复时,采用新功能的风险很高。

以下是 1.x 策略的一个例子:


使用 1.8.1开发的应用程序无法吸收 1.8.2 的功能,或者通过反向移植修复和维护新的发行版,无法采用 1.8.3错误修复。


Electron 发行版
Electron 常见问题 (FAQ)
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }