当上游依赖项发生变化时提升语义版本化的工件
Promoting semantically versioned artifacts when an upstream dependency has changed
我正在计划将我们的 build.gradle 文件转换为使用语义版本。除了使用 Gradle,我们还使用 Git 并遵循 Gitflow 工作流程。 Jenkins 用于构建项目。
已发布工件的版本遵循 MAJOR.MINOR.PATCH 格式。在build.gradle文件中声明依赖时,我们使用动态版本,比如10.0.+(即取最新的10.0.PATCH版本)。
我们将我们的工件从 Release Candidates 存储库提升到 Nexus 中的 Releases 存储库。存储库的策略设置为 "Releases"。由于产品的复杂性(200+项目,上下游依赖较多),很多Jenkins可用的推广插件显得力不从心。我们正在考虑让 Jenkins 构建主分支作为重命名工件(10.0.0-rc.1-abcdefg 变为 10.0.0)并将它们上传到正确的 Nexus 存储库的方法。
我不确定如何处理上游依赖项的补丁版本增加的情况。下游项目 - WAR - 由 Jenkins 重新构建并捆绑新的 JAR,但下游项目的版本没有改变。尝试上传到 Nexus 时失败,因为只有一个工件可以具有相同的版本。
这是一个例子:
- Releases Nexus 存储库的上游-api 版本为 10.0.0,下游项目版本为 10.0.0
- 下游项目依赖于 10.0.+ 的上游-api
- 上游-api.jar 被捆绑到下游-project.war 文件
- 这两个工件作为产品版本 X 的一部分进行部署
- 当一个hotfix分支合并到master时,upstream-api版本已经更改为10.0.1
- 修复意味着在部署时,产品现在是版本 X'
- downstream-project 保持在 10.0.0,但由于 upstream 依赖项的变化而被重新构建
- Jenkins 无法将 downstream-project-10.0.0.war 上传到 Nexus,因为它已经存在
我可以用新工件替换旧工件,但这意味着版本 X 不能再从 Nexus 中的工件部署(例如,在回滚的情况下,或需要在较旧的版本)。
这通常是如何处理的?
How is this typically handled?
我这里没有通用的答案。我假设这些是最“常见”的可能性:
不要随发行版分发您的依赖项并继续使用依赖项版本声明,例如 10.0.+
。然后假设该软件确实可以与 any 10.0.x 版本一起使用 – 至少在您的用户可以容忍的范围内。这通常发生在以源代码或 Linux 发行版的软件包系统分发的免费软件中。依赖版本声明仅在依赖需要改进时更新,即当更改非常重要以至于您的用户无法容忍任何早期版本时。
随发行版分发您的依赖项,并且:
- 除了原始代码的 main/semantic 版本号之外,还使用内部版本号 – 例如 1.3.4-b3。如果我没记错的话,这通常是针对专有 Windows 软件进行的。
- 当依赖项发生变化时增加 main/semantic 版本号并使依赖项要求明确。
关于这个问题的一些更一般的想法
我认为核心问题是动态依赖声明——10.0.+
版本声明。您在此声明中声明的是,您的版本与 任何 10.0.x 版本同样有效。
如果确实如此,即由依赖项中的补丁修复的错误保证到永远不会 影响发布,那么您的发布可能根本不应该重建,因为它的功能无论如何都不会改变。依赖的版本无关紧要,您的发布可以保留旧的依赖版本。
不过,更有可能的是,上游错误修复也会对您的下游项目产生影响,即它们会影响发行版的功能。在那种情况下,您应该在 build.gradle
中明确显示“新”依赖项。由于这是对您的发布工件的更改,因此新的发布版本到期了。
我正在计划将我们的 build.gradle 文件转换为使用语义版本。除了使用 Gradle,我们还使用 Git 并遵循 Gitflow 工作流程。 Jenkins 用于构建项目。
已发布工件的版本遵循 MAJOR.MINOR.PATCH 格式。在build.gradle文件中声明依赖时,我们使用动态版本,比如10.0.+(即取最新的10.0.PATCH版本)。
我们将我们的工件从 Release Candidates 存储库提升到 Nexus 中的 Releases 存储库。存储库的策略设置为 "Releases"。由于产品的复杂性(200+项目,上下游依赖较多),很多Jenkins可用的推广插件显得力不从心。我们正在考虑让 Jenkins 构建主分支作为重命名工件(10.0.0-rc.1-abcdefg 变为 10.0.0)并将它们上传到正确的 Nexus 存储库的方法。
我不确定如何处理上游依赖项的补丁版本增加的情况。下游项目 - WAR - 由 Jenkins 重新构建并捆绑新的 JAR,但下游项目的版本没有改变。尝试上传到 Nexus 时失败,因为只有一个工件可以具有相同的版本。
这是一个例子:
- Releases Nexus 存储库的上游-api 版本为 10.0.0,下游项目版本为 10.0.0
- 下游项目依赖于 10.0.+ 的上游-api
- 上游-api.jar 被捆绑到下游-project.war 文件
- 这两个工件作为产品版本 X 的一部分进行部署
- 当一个hotfix分支合并到master时,upstream-api版本已经更改为10.0.1
- 修复意味着在部署时,产品现在是版本 X'
- downstream-project 保持在 10.0.0,但由于 upstream 依赖项的变化而被重新构建
- Jenkins 无法将 downstream-project-10.0.0.war 上传到 Nexus,因为它已经存在
我可以用新工件替换旧工件,但这意味着版本 X 不能再从 Nexus 中的工件部署(例如,在回滚的情况下,或需要在较旧的版本)。
这通常是如何处理的?
How is this typically handled?
我这里没有通用的答案。我假设这些是最“常见”的可能性:
不要随发行版分发您的依赖项并继续使用依赖项版本声明,例如
10.0.+
。然后假设该软件确实可以与 any 10.0.x 版本一起使用 – 至少在您的用户可以容忍的范围内。这通常发生在以源代码或 Linux 发行版的软件包系统分发的免费软件中。依赖版本声明仅在依赖需要改进时更新,即当更改非常重要以至于您的用户无法容忍任何早期版本时。随发行版分发您的依赖项,并且:
- 除了原始代码的 main/semantic 版本号之外,还使用内部版本号 – 例如 1.3.4-b3。如果我没记错的话,这通常是针对专有 Windows 软件进行的。
- 当依赖项发生变化时增加 main/semantic 版本号并使依赖项要求明确。
关于这个问题的一些更一般的想法
我认为核心问题是动态依赖声明——10.0.+
版本声明。您在此声明中声明的是,您的版本与 任何 10.0.x 版本同样有效。
如果确实如此,即由依赖项中的补丁修复的错误保证到永远不会 影响发布,那么您的发布可能根本不应该重建,因为它的功能无论如何都不会改变。依赖的版本无关紧要,您的发布可以保留旧的依赖版本。
不过,更有可能的是,上游错误修复也会对您的下游项目产生影响,即它们会影响发行版的功能。在那种情况下,您应该在
build.gradle
中明确显示“新”依赖项。由于这是对您的发布工件的更改,因此新的发布版本到期了。