关于软件版本号的问题 软​件​版​本​号​命​名​规​则

关于软件版本号的问题

   完全的版本号定义,分三项::<主版本号>.<次版本号>.<修订版本号>,如 1.0.0。

1.版本号升级原则:

   主版本号:功能模块有大的变动,比如增加多个模块或者整体架构发生变化。  

   次版本号:和主版本相对而言,次版本号的升级对应的只是局部的变动。但该局部的变动造成了程序和以前版本不能兼容,或者对该程序以前的协作关系产生了破坏,或者是功能上有大的改进或增强。  

   修订版本号:局部的变动,主要是局部函数的功能改进,或者bug的修正,或者功能的扩充。

------------------------------------------------------------------------------------

   各种软件的版本号是怎么确定的,怎样的跨越才能算是由bate到正式版?原则上,自第一个稳定版本发布后,修订版本号会经常性改动,而次版本号则依情况作改动,主版本号改动的频率很低,除非有大的重构或功能改进。对于小项目而言,甚至可以简化为:>.<次版本号>.<修订版本号>。版本号比较自由,至于Beta版或者是正式版跟版本号之间并没有任何关系,只要达到正式版的要求的话,即使版本号是1.0或者0.1都可能是正式版的。  

   * Alpha版: 此版本表示该软件在此阶段主要是以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改。  

   * Beta版: 该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI。  

   * RC版: 该版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。  

   * Release版: 该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号(R)。 

2. 版本命名规范

   软件版本号由四部分组成,第一个1为主版本号,第二个1为子版本号,第三个1为阶段版本号,第四部分为日期版本号加希腊字母版本号,希腊字母版本号共有5种,分别为:base、alpha、beta、RC、release。例如:1.1.1.051021_beta。 

3. 版本号定修改规则

   * 主版本号:当功能模块有较大的变动,比如增加多个模块或者整体架构发生变化。此版本号由项目决定是否修改。 

   * 子版本号:当功能有一定的增加或变化,比如增加了对权限控制、增加自定义视图等功能。此版本号由项目决定是否修改。

   * 阶段版本号一般是 Bug 修复或是一些小的变动,要经常发布修订版,时间间隔不限,修复一个严重的bug即可发布一个修订版。此版本号由项目经理决定是否修改。 

   * 日期版本号(051021):用于记录修改项目的当前日期,每天对项目的修改都需要更改日期版本号。此版本号由开发人员决定是否修改。

   * 希腊字母版本号(beta):此版本号用于标注当前版本的软件处于哪个开发阶段,当软件进入到另一个阶段时需要修改此版本号。此版本号由项目决定是否修改。


语义化的版本控制 2.0.0-rc.1

在软件管理世界里存在着被称作“依赖地狱”的死亡之谷,系统规模越大,引入的程序包越多,你就越有可能在不久的将来发现自己深陷绝望之中。

在多依赖的系统中发布新版本程序包很快成为噩梦。如果依赖关系过紧密,可能面临版本控制被锁死的风险(必须对每一个依赖程序包改版才能完成某次升级)。而如果依赖关系过于松散,又无法避免版本混乱(\产生超过合理值的版本数/)。当你项目的进展由于版本控制被锁死和/或版本混乱变得不那么简便和可靠,也就意味着你正处于依赖地狱之中。

为了解决这个问题,我提议通过一些规则和约束来表述版本号如何命名及何时更新。要使此系统正常运作,你首先需要声明一个公共应用程序接口(以下简称API)。可以\以文档形式或代码形式实施/。需要注意的是,这个API必须是清晰和明确的。一旦公共API确定下来,你将通过版本号增量来描述版本修改。形如X.Y.Z(主版本号.副版本号.补丁号)这样的版本格式。通过增加补丁号来表示不影响API的错误修复,增加副版本号来表示兼容现有API的扩展/修改,而增加主版本号则表示不兼容现有API的修改。

我称这套系统为“语义化的版本控制”,在这套约定下,版本号及其更新方式 包含了相邻版本间的\底层/代码和修改部分的信息。

语义化版本控制说明(SemVer)

文档中出现的“必须”,“禁止”,“要求”,“应该”,“不该”,“可能”,“可能不”,“建议”,“也许”,和“可选”按RFC 2119规范解读。

  1. 使用语义化版本控制的软件必须 声明公共API。该API可以在代码中声明也可以固化为文档。无论何种形式,API\应该/是明确而全面的。

  2. 标准的版本号必须采用X.Y.Z的格式,其中X,Y,和Z为非负的整数。X是主版本号,Y是副版本号,而Z为补丁号。每个元素必须 取数值1为增量。例如:1.9.1->1.10.0->1.11.0。

  3. 标记版本号的软件包发布后,禁止改变该版本软件包的内容。任何修改都必须以新版本发布。

  4. 主版本号为0(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共API不应该被视为稳定版。

  5. 1.0.0版本用于\界定/公共API的形成。这一版本之后所有的版本号更新都基于公共API及其修改。

  6. 补丁号Z(x.y.Z | x>0)必须增加,仅在兼容原有接口的错误修复被引入时。错误修复指的是对不正确反应修复而进行的\内部修改/。

  7. 副版本号Y (x.Y.z | x>0)必须增加,如果新的、兼容原有接口的功能被引入公共API;或者任何公共API被标记为弃用。副版本号可能增加,如果大量新功能或者改进被通过私有代码引入。这一过程中可能包含补丁级别的改变。当副版本号增加时补丁号必须置零。

  8. 主版本号X (X.y.z | X>0) 必须增加,如果任何不兼容原有接口的改变被引入到公共API,这一过程中可能包含副版本级别和补丁级别的改变。当主版本号增加时补丁号和副版本号必须置零。

  9. 预发布版本可以通过紧跟在补丁号后的一个破折号和一系列点号分隔的标识符来修饰。这些标识符必须由ASCII码和破则号[0-9A-Za-z-]组成。预发布版本\满足需求/但优先级低于相关联的标准版本。例如: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92。

  10. 构建版本可以通过紧跟在补丁号或者预发布本本号后的一个加号和一系列点号分隔的标识符来修饰。这些标识符必须由ASCII码和破则号[0-9A-Za-z-]组成。构建版本\满足需求/且优先级高于相关联的标准版本。例如:1.0.0+build, 1.3.7+build.11.e0f985a。

  11. 优先级必须通过将版本号按主版本号,副版本号,补丁号,预发布版本号,和构建版本号顺序拆分后计算。主版本号,副版本号和补丁号以数值大小比较。预发布和构建版本号必须通过如下方式将点号分隔的每一标识符比较来确定:仅包含数字的标识符以数值大小比较,含字母或破则号的以ASCII排序比较。数字标识符的优先级低于非数字标识符。例如: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0-rc.1+build.1 < 1.0.0 < 1.0.0+0.3.7 < 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a 。

为什么要使用语义化的版本控制?

这并不是一个新的或者革命性的主意。实际上,你可能已经在做一些近似的事情了。问题在于光“近似”还不够。如果没有一些正式的规范可循,版本号对于依赖管理并无实质意义。通过为这一主意命名并给予清晰的定义,让你向软件使用者传达意向变得更为轻松。一旦这些意向变得清晰,灵活(而不过于灵活)依赖关系就能最终确定。

举个例子来展示语义化的版本控制如何让依赖地狱成为过去。假设有一个名为“救火车”的库依赖另一个名为“梯子”的已纳入语义版本控制的库。救火车创建时,梯子的版本号为3.1.0。因为救火车调用的是3.1.0版本中的一些功能函数,你可以放心的指定梯子依赖为版本号大等于3.1.0而小于4.0.0。这样,当梯子版本3.1.1和3.2.0发布时,你就可以将直接它们纳入你的程序包管理系统,因为它们能与原有依赖软件兼容。

作为一位负责任的开发者,你当然也会确保每个程序升级包的运行与表述一致。现实世界是复杂的,我们除了独善其身外能做的不多。你所能做的就是让语义化版本控制为你提供健全的程序包发布和升级方式,而无需\重新整理程序包依赖/,节省时间减少烦恼。

如果你对此认同,希望立即开始使用语义化版本控制,你只需声明正在使用它并遵循这些规则就可以了。请在你的README文档中保留此页链接,让别人也知道这些规则并重中受益。

FAQ

在0.y.z初始化开发阶段,我该如何完成版本修订?

最简单的做法是以0.1.0作为你的初始化开发版本,在后续发布中增加副版本号。

如何判断发布1.0.0版本的时机?

当你的软件被用于生产环境,就很可能已经处于1.0.0阶段了。如果使用者信赖你稳定的API,也应该发布1.0.0版本。如果你为兼容原有接口而担心,你可能已经处于1.0.0阶段了。

这不会阻碍快速开发和迭代?

主版本号为0完全为快速开发而存在。如果你每天都在改版API,那么你不是处在0.x.x版本就是处在可能成为下一主版本的独立分支的开发工作中。

如果对公共API的每个微小但不兼容的改变都需要产生新的主版本呢 ,岂不会导致版本号很快达到42.0.0?

这实际上是开发者责任感和前瞻性的问题。不兼容的改变不应该轻易被引入被大量依赖的代码中。升级所付出的代价可能是巨大的。不兼容的改变将增加主版本号意味着你必须为这些改变带来的影响深思熟虑,并评估相关的成本/受益率。

为全部公共API写文档的工作量太大了!

为供他人使用的软件编写完整的文档这是你作为一名专业开发者应尽的职责,控制软件复杂性是保持项目高 效的艰巨而重要的部分。如果没有人知道如何使用你的软件或者不知道对某个方法的调用是是否可靠,这(控制软件复杂性)将很难完成。而语义化版本控制,以及坚持对公共API的合理定义,可以保证每个人每件事运行顺畅。

万一不小心把一个不兼容的改变作为副版本发布了该怎么办?

一旦发现自己破坏了语义化版本控制规则,要尽快修复问题,并发布一个纠正问题且兼容原有接口的副版本。记住,修改一个已发布版本的内容是不可接受的,即便在这种情况下。合适的情况下,将犯错的版本写入文档,告诉使用者问题所在,让他们能够意识到这是有问题的版本。

如果我更新了自己的依赖性却没有改变公共API该怎么办?

如果不影响公共API则认为此次更新是兼容的。和你的程序包有相同依赖关系的软件应该会有它自己的依赖关系说明,如有冲突软件作者会在其中提出。此次改变是补丁级别还是副版本级别则取决于你更新依赖关系是想要修复bug还是引入新功能。后一种情况通常伴随着附加代码,这显然应该被判为副版本级别的更新。

如果正在修复的bug会产生与公共API不一致的代码该怎么办?(例如由于失误导致代码与公共API文档不同步)

依靠你的判断,如果你有一个大用户会由于行为回滚到公共API文档而\彻底困扰/,那么你可能应该进行一次主版本级别的更新,尽管这些修复从严格意义上来说是补丁级别发布。记住,语义化的版本控制的全部精义在于通过版本号的变化来传达意向。如果这些改变对于用户来说是重要的,请通过变更版本号来通知他们。

如何处理即将弃用的功能?

弃用现存的功能是软件开发中的家常便饭,也通常是向前发展所必须的。但当你弃用公共API的一部分时,你应该做两件事:(1)更新文档以便使用者知道这个变化。(2)发行不包含弃用功能的副版本。在新主版本中完全移除弃用功能前,至少应有一个不包含弃用功能的副版本发布,以便使用者能够平滑过渡到新API。

关于

语义化的版本控制说明由Gravatars创办者兼Github共同创办者 Tom Preston-Werner 所著。

如需反馈,请在Github上创建issue


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值