模块发布与版本管理工作流程
当您开发供其他开发者使用的模块时,可以遵循一套工作流程,这有助于确保使用该模块的开发者获得可靠且一致的体验。本主题将介绍该工作流程的高级步骤。
有关模块开发的概述,请参阅开发与发布模块。
另请参阅
常见工作流程步骤
以下序列展示了示例新模块的发布与版本管理工作流程步骤。有关每个步骤的更多信息,请参阅本主题中的相关章节。
-
开始构建一个模块并组织其源代码,以使开发者更易于使用,并使您更易于维护。
如果您是模块开发新手,请查看教程:创建一个Go模块。
在Go的去中心化模块发布系统中,您组织代码的方式至关重要。更多信息请参阅管理模块源代码。
-
设置环境以编写本地客户端代码,该代码调用未发布模块中的函数。
在发布模块之前,它无法用于典型的依赖管理工作流程(例如使用
go get等命令)。在此阶段测试模块代码的一个好方法是,尝试在调用代码所在的本地目录中使用它。更多关于本地开发的信息,请参阅针对未发布模块进行编码。
-
当模块代码准备就绪可供其他开发者试用时,开始发布 v0 预发布版本,例如 alpha 和 beta 版。更多信息请参阅发布预发布版本。
-
发布一个 v0 版本,该版本不保证稳定性,但用户可以试用。更多信息请参阅发布首个(不稳定的)版本。
-
在您的 v0 版本发布后,您可以(并且应该!)继续发布其新版本。
这些新版本可能包括错误修复(补丁版本)、对模块公共 API 的添加(次要版本),甚至破坏性更改。因为 v0 版本不保证稳定性或向后兼容性,您可以在其版本中进行破坏性更改。
更多信息请参阅发布错误修复和发布非破坏性API变更。
-
当您准备好发布一个稳定版本时,您可以发布预发布版本(alpha 和 beta 版)。更多信息请参阅发布预发布版本。
-
发布 v1 作为首个稳定版本。
这是第一个对模块稳定性做出承诺的版本。更多信息请参阅发布首个稳定版本。
-
在 v1 版本中,继续修复错误,并在必要时对模块的公共 API 进行添加。
更多信息请参阅发布错误修复和发布非破坏性API变更。
-
当无法避免时,在新的主版本中发布破坏性更改。
主版本更新(例如从 v1.x.x 到 v2.x.x)对您的模块用户来说可能是一个非常破坏性的升级。这应该是最后的手段。更多信息请参阅发布破坏性API变更。
针对未发布模块进行编码
当您开始开发一个模块或模块的新版本时,您尚未发布它。在发布模块之前,您将无法使用 Go 命令将该模块添加为依赖项。相反,最初在另一个模块中编写调用未发布模块函数的客户端代码时,您需要引用文件系统上该模块的本地副本。
您可以通过在客户端模块的 go.mod 文件中使用 replace 指令,从客户端模块的 go.mod 文件中本地引用一个模块。有关更多信息,请参阅在本地目录中需要模块代码。
发布预发布版本
您可以发布预发布版本,使模块可供他人试用并向您提供反馈。预发布版本不保证稳定性。
预发布版本号会附加一个预发布标识符。有关版本编号的更多信息,请参阅模块版本编号。
以下是两个示例:v0.2.1-beta.1 v1.2.3-alpha在提供预发布版本时,请注意使用该预发布版本的开发者需要在 go get 命令中显式指定该版本。这是因为默认情况下,go 命令在查找您所需的模块时,会优先选择正式发布版本而非预发布版本。因此,开发者必须通过显式指定来获取预发布版本,如下例所示:```
go get example.com/theirmodule@v1.2.3-alpha
## 发布首个(不稳定)版本 {#first-unstable}
与发布预发布版本类似,您可以发布不保证稳定性或向后兼容性的正式版本,但能让用户体验模块功能并提供反馈。
不稳定版本是指版本号处于 v0.x.x 范围内的发布版本。v0 版本不提供稳定性或向后兼容性保证,但能让您在通过 v1 及更高版本做出稳定性承诺前获取反馈并优化 API 设计。更多详情请参阅[模块版本编号](version-numbers)。
与其他已发布版本类似,您可以在向稳定 v1 版本演进的过程中递增 v0 版本号的次要版本和修订版本。例如,在发布 v0.0.0 后,您可以发布包含首批错误修复的 v0.0.1 版本。
以下是一个版本号示例:
v0.1.3
v0.1.3
```您可以通过标记仓库中的模块代码来发布不稳定版本,在标记中指定 v0 版本号。更多详情请参阅[发布模块](publishing)。
## 发布第一个稳定版本 {#first-stable}
您的第一个稳定版本将具有 v1.x.x 版本号。第一个稳定版本是在预发布版本和 v0 版本之后发布的,通过这些版本您收集了用户反馈、修复了错误,并使模块趋于稳定。
发布 v1 版本时,您正在向使用您模块的开发者做出以下承诺:
* 他们可以升级到该主版本的后续次要版本和修订版本,而不会破坏他们自己的代码。
* 您将不会对模块的公共 API(包括其函数和方法签名)进行任何会破坏向后兼容性的进一步更改。
* 您将不会移除任何导出的类型,否则这会破坏向后兼容性。
* 未来对您 API 的更改(例如向结构体添加新字段)将是向后兼容的,并将包含在新的次要版本中。
* 错误修复(例如安全修复)将包含在修订版本中,或作为次要版本的一部分。
**注意:** 虽然您的第一个主版本可能是 v0 版本,但 v0 版本并不表示稳定性或向后兼容性保证。因此,当您从 v0 升级到 v1 时,无需担心破坏向后兼容性,因为 v0 版本本就不被视为稳定版本。
有关版本号的更多信息,请参阅[模块版本编号](/doc/modules/version-numbers)。
这是一个稳定版本号的示例:```
v1.0.0
```您可以通过在代码仓库中标记模块代码并指定 v1 版本号来发布首个稳定版本。更多信息请参阅[发布模块](publishing)。
## 发布错误修复 {#bug-fixes}
您可以发布仅包含错误修复的变更版本,这称为_补丁版本_。
_补丁版本_仅包含较小的更改,特别是不会对模块的公共 API 进行任何更改。使用方代码的开发者可以安全地升级到此版本,无需修改自己的代码。
**注意:** 您的补丁版本应尽量避免将该模块自身的传递依赖项升级超过一个补丁版本范围。否则,升级您模块补丁版本的用户可能会意外引入对其使用的传递依赖项的较大变更。
补丁版本会增加模块版本号的补丁部分。更多信息请参阅[模块版本编号](/doc/modules/version-numbers)。
在以下示例中,v1.0.1 是一个补丁版本。
旧版本:`v1.0.0`
新版本:`v1.0.1`
您可以通过在代码仓库中标记模块代码并增加标记中的补丁版本号来发布补丁版本。更多信息请参阅[发布模块](publishing)。
## 发布非破坏性 API 变更 {#non-breaking}
您可以对模块的公共 API 进行非破坏性更改,并通过_次要_版本发布这些变更。
此版本会更改 API,但不会以破坏调用方代码的方式进行。这可能包括更改模块自身的依赖项,或添加新的函数、方法、结构体字段或类型。即使包含这些更改,此类版本也保证了调用模块函数的现有代码的向后兼容性和稳定性。
次要版本会增加模块版本号的次要部分。更多信息请参阅[模块版本编号](/doc/modules/version-numbers)。
在以下示例中,v1.1.0 是一个次要版本。
旧版本:`v1.0.1`
新版本:`v1.1.0`
您可以通过在代码仓库中标记模块代码并增加标记中的次要版本号来发布次要版本。更多信息请参阅[发布模块](publishing)。
## 发布破坏性 API 变更 {#breaking}
您可以通过发布_主要_版本来发布破坏向后兼容性的版本。
主要版本不保证向后兼容性,通常因为它包含了对模块公共 API 的更改,这些更改会破坏使用该模块早期版本的代码。
鉴于主要版本升级可能对依赖该模块的代码造成破坏性影响,如果可以,您应避免进行主要版本更新。有关主要版本更新的更多信息,请参阅[开发主要版本更新](/doc/modules/major-version)。有关避免进行破坏性更改的策略,请参阅博文[保持模块兼容性](/blog/module-compatibility)。
发布其他类型的版本本质上需要使用版本号标记模块代码,而发布主要版本更新则需要更多步骤。
1. 在开始开发新主要版本之前,请在您的代码仓库中为新版本的源代码创建存放位置。
一种方法是在您的代码仓库中创建一个专门用于新主要版本及其后续次要和补丁版本的新分支。更多信息请参阅[管理模块源代码](/doc/modules/managing-source)。
1. 在模块的 go.mod 文件中,修改模块路径以附加新的主要版本号,如以下示例所示:```
example.com/mymodule/v2
```鉴于模块路径是模块的标识符,此更改实际上创建了一个新的模块。同时也改变了包路径,确保开发者不会无意中导入会破坏其代码的版本。相反,希望升级的开发者需要显式地将旧路径替换为新路径。
1. 在您的代码中,更新所有导入该模块内包的包路径,包括您正在更新的模块中的包。这是必要的,因为您已经更改了模块路径。
1. 与任何新版本发布一样,您应该发布预发布版本以获取反馈和错误报告,然后再发布正式版本。
1. 通过标记您仓库中的模块代码来发布新的主要版本,并在标记中递增主版本号——例如从 v1.5.2 到 v2.0.0。
更多信息,请参阅[发布模块](/doc/modules/publishing)。