当前位置: 首页 > news >正文

语义版本号(Semantic Versioning)

版本号格式不陌生吧,.NET 传统的版本号格式类似这样 1.5.1254.0。本文将推荐一种新的版本号格式——语义版本号,格式类似这样 1.4.6-beta。我推荐语义版本号是因为这样的版本号自包含语义,而且这样的语义能够在版本库中体现出来。


传统的版本号

如果你只是知道传统版本号由四个部分组成,那么建议去官方文档 Assembly Versioning 了解一下这种版本号的定义。它分为 主版本号.次版本号.构建号.修订号 四个部分,但是后面的一个或多个部分可以省略。

AssemblyVersion

例如,1.5.1254.0 表示主版本号是 1,次版本号是 5;在 1.5 的版本下,第 1255 次构建,并且在这次构建之后没有进行修订。如果你是一个库的发布者,那么主版本号的改变意味着 API 出现不兼容的修改;次版本号改变意味着 API 出现兼容的修改(通常是新增)。

new Version()

然而我们如何能够准确地向所有人传递这样的版本规则呢?当我们在向全世界提供一个库(比如 NuGet 包)的时候,我们怎么让团队所有人都知道我们正在为哪个版本开发新功能呢?我们又应该在何时更新程序集或者 NuGet 的版本号呢(在功能开发开始?差不多完成?临近发布?)?

传统的版本号记录不了这些信息,于是我们不得不用一些额外的方式来记录,这就增加了维护成本。

语义版本号

语义版本号由五个部分组成 主版本号次版本号补丁号预发布版本标签构建号。举例看看语义版本号是什么样的吧(摘自 NuGet Package Version Reference):

  • 1.0.1
  • 1.0.1-rc
  • 1.0.1-beta
  • 1.0.1-alpha2
  • 1.0.1-alpha
  • 1.0.1-aaa

NuGet 4.3.0 以上,并且 Visual Studio 2017 的 15.3 以上版本开始支持语义版本号 2.0(Semantic Versioning 2.0.0)。

  • 1.0.0-alpha.1
    • 2.0 版本的语义版本号在预发布标签后面使用 . 来区分预发布的不同版本,这样就能避免 alpha2 在字符串比较上大于 alpha10 的问题。(否则得写成 alpha02 了。)
  • 1.0.0+githash
    • 2.0 版本的语义版本号在最后使用 + 来表示 git 版本库相关的信息,这样为持续集成(CI)时自动生成版本号提供了方便。
  • 1.0.0-beta.5+4
    • 表示这是准备发布 1.0.0 的第 5/6 个 beta 版本之后,又新增了 4 个 git 提交。(是不是意义更加明确?)

如何在项目中使用语义版本号?

如果你希望方便,在执行 dotnet builddotnet pack 命令之后能够直接得到使用语义版本号的 NuGet 包,那么你必须拥有一个新格式的 csproj,就是 .NET Core 带来的那种新格式。如果你的格式是旧的,可以阅读我的另一篇文章 将 WPF、UWP 以及其他各种类型的旧样式的 csproj 文件迁移成新样式的 csproj 文件 迁移成新格式。

这样,在 csproj 文件中将版本号写为以下方式即可:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <Version>1.6.2-beta</Version>
    <!-- <PackageId>Walterlv.DemoPackage</PackageId> -->
    <!-- <TargetFrameworks>netstandard2.0;net471</TargetFrameworks> -->
  </PropertyGroup>
</Project>

你还可以考虑在编译的时候进行改变,即执行编译命令的时候传入版本号:

# 以下三种都行
> dotnet build /p:Version=1.6.2-beta
> dotnet msbuild /p:Version=1.6.2-beta
> msbuild /p:Version=1.6.2-beta

当然,你还可以使用响应文件来简化参数,详情可阅读我的另一篇博客 使用 MSBuild 响应文件 (rsp) 来指定 dotnet build 命令行编译时的大量参数。

如果希望自动化地在项目中生成语义版本号,可阅读我的另一篇博客 使用 GitVersion 在编译或持续构建时自动使用语义版本号(Semantic Versioning)。


参考资料

  • Semantic Versioning 2.0.0 - Semantic Versioning
  • Semantic Versioning & auto-incremented NuGet package versions - Xavier Decoster
  • NuGet Package Version Reference - Microsoft Docs
  • Pre-release versions in NuGet packages - Microsoft Docs
  • Versioning NuGet packages in a continuous delivery world: part 1 – Microsoft DevOps Blog
  • Versioning NuGet packages in a continuous delivery world: part 3 – Microsoft DevOps Blog
  • Supporting Semantic Versioning 2.0.0

相关文章:

  • 使用 GitVersion 在编译或持续构建时自动使用语义版本号(Semantic Versioning)
  • UWP 流畅设计中的光照效果(容易的 RevealBorderBrush 和不那么容易的 RevealBackgroundBrush)
  • 使用 Emit 生成 IL 代码
  • 如何快速编写和调试 Emit 生成 IL 的代码
  • 自动将 NuGet 包的引用方式从 packages.config 升级为 PackageReference
  • 冷算法:自动生成代码标识符(类名、方法名、变量名)
  • WPF/UWP 的 Grid 布局竟然有 Bug,还不止一个!了解 Grid 中那些未定义的布局规则
  • Git 更安全的强制推送,--force-with-lease
  • 项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
  • 理解 C# 项目 csproj 文件格式的本质和编译流程
  • 如何创建一个基于命令行工具的跨平台的 NuGet 工具包
  • 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包
  • 如何最快速地将旧的 NuGet 包 (2.x, packages.config) 升级成新的 NuGet 包 (4.x, PackageReference)
  • 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译
  • C# 中那些可以被重载的操作符,以及使用它们的那些丧心病狂的语法糖
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • Js基础知识(四) - js运行原理与机制
  • React-生命周期杂记
  • Spark学习笔记之相关记录
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 订阅Forge Viewer所有的事件
  • 分享一份非常强势的Android面试题
  • 构建工具 - 收藏集 - 掘金
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 网页视频流m3u8/ts视频下载
  • 运行时添加log4j2的appender
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​插件化DPI在商用WIFI中的价值
  • ​渐进式Web应用PWA的未来
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #pragma 指令
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (bean配置类的注解开发)学习Spring的第十三天
  • (C语言)fread与fwrite详解
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (NSDate) 时间 (time )比较
  • (SpringBoot)第二章:Spring创建和使用
  • (二)pulsar安装在独立的docker中,python测试
  • (二)springcloud实战之config配置中心
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .net core 控制台应用程序读取配置文件app.config
  • .NET Core 中的路径问题
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NetCore项目nginx发布
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET企业级应用架构设计系列之结尾篇
  • /bin/rm: 参数列表过长"的解决办法
  • ??javascript里的变量问题
  • @Autowired多个相同类型bean装配问题