跳到主要内容

JEP 369:迁移到 GitHub

QWen Max 中英对照 JEP 369: Migrate to GitHub

总结

GitHub 上托管 OpenJDK 社区的 Git 仓库。结合 JEP 357(从 Mercurial 迁移到 Git),这将会把所有单一仓库的 OpenJDK 项目迁移到 GitHub,包括 JDK 特性发布 和版本 11 及之后的 JDK 更新发布

目标

  • https://github.com/openjdk/ 上托管所有 OpenJDK Git 仓库。
  • 在每次推送之前运行预提交检查(jcheck)。
  • 集成现有的 OpenJDK 服务。
  • 启用与 GitHub 交互的多种方式。
  • 确保支持在结构上类似于现有电子邮件和 webrev 工作流的工作流。
  • 保留并归档所有元数据。
  • 确保 OpenJDK 社区始终可以迁移到其他源代码托管提供商。
  • 不要求开发者安装 OpenJDK 特定工具即可贡献代码。
  • 不更改 OpenJDK 章程
  • 不更改 OpenJDK 人口普查

非目标

我们的目标并不是要更改 OpenJDK 社区的 问题跟踪器wiki 或任何其他现有的基础设施。

成功指标

  • 显著更快的克隆和拉取时间
  • 更好的仓库可用性(正常运行时间)
  • 可以通过 OpenJDK 邮件列表与 GitHub 上的仓库进行交互
  • 可以通过命令行工具与 GitHub 上的仓库进行交互
  • 可以通过网页浏览器与 GitHub 上的仓库进行交互

动机

此 JEP 的动机分为两部分。首先,我们讨论为什么使用外部源代码托管服务提供商将使 OpenJDK 社区受益,然后我们解释为什么 GitHub 是目前最佳的服务提供商选择。

为什么选择外部源代码托管提供商?

外部源代码托管提供商是指并非由 OpenJDK 社区中的贡献者实施和管理的源代码存储库服务。外部提供商的示例包括 BitBucketGitLabPhacilitySourceForgeGitHub

OpenJDK 社区使用外部源代码托管服务提供商主要有三个原因:

  • 性能。许多(如果不是全部的话)提供商都有出色的性能,不仅在网络性能方面,在可用性(即正常运行时间)方面也是如此。对于 OpenJDK 社区来说,这将显著加快克隆和拉取的时间,并且源代码仓库的可用性会更高。

  • API。将 OpenJDK 仓库托管在源代码托管平台上的一个技术原因是获得访问 Web API 的权限,这些 API 能让程序与平台上的开发者进行交互。尽管目前通过电子邮件与开发者互动也能实现这一目标,但开发能够解析电子邮件中自由格式文本的程序要困难得多,而使用结构化的 API 则相对容易。允许程序参与评审过程可以实现强大的自动化;有关几个示例,请参见描述部分。

  • 扩展社区。最大的提供商还将为 OpenJDK 社区提供机会,接触大量现有的开发者和潜在贡献者。如果开发者已经在某个提供商上拥有账户,则只需很少的额外步骤即可为 OpenJDK 做出贡献。较大的 Java 社区中的几乎所有开源项目都托管在外部提供商上,其中包括多个 OpenJDK 发行版。如果 OpenJDK 仓库也托管在同一提供商上,这将促进更紧密的合作。

使用外部供应商的一个缺点和风险是,供应商可能会关闭,或者由于其他原因导致源代码和相关资料无法访问。有关如何处理和缓解此风险的信息,请参见风险与假设部分。

另一个需要考虑的因素是,转移到外部供应商会对现有贡献者的工作流程产生什么影响。请参阅 Description 部分,了解如何在源代码托管平台的 API 帮助下支持多种工作流程,包括如何保留几乎所有的 OpenJDK 社区现有工作流程。

为什么选择 GitHub?

选择 GitHub 的动机在于,它在选择外部提供商的三个主要原因上都表现出色。GitHub 的性能与其他提供商一样好或更优,它是全球最大的源代码托管服务(截至 2020 年 5 月已有 5000 万用户),并且拥有最广泛的 API 之一。

GitHub 广泛的 API 使得许多工具(包括文本编辑器、IDE、命令行工具和图形桌面客户端)都能够支持 GitHub。以下文本编辑器支持 GitHub(即,开发者可以直接在文本编辑器中创建、审查和评论拉取请求):

以下集成开发环境(IDE)支持与 GitHub 上的拉取请求进行交互:

还有命令行形式的客户端,例如 hub(开源),以及多个图形化的桌面客户端,例如 SourceTreeTowerGitHub Desktop(开源)。

还有许多其他优秀的源代码托管服务提供商。有关这为何重要以及这如何使我们能够推荐 GitHub,请参见风险与假设部分。

描述

迁移到外部源代码托管服务提供商的有趣之处 并不在于 将实际的代码仓库上传到该服务;鉴于 JEP 357(从 Mercurial 迁移到 Git) 中的工作,这一步非常简单。
真正有趣的是,迁移到外部提供商将如何影响 OpenJDK 贡献者的工作流程。

如今,OpenJDK 的贡献者通过邮件列表进行协作,他们将更改推送到Mercurial 仓库,通过jdk/submit服务测试更改,并通过JDK Bug 系统(JBS)提交错误报告。贡献者还可以使用多个命令行界面(CLI)工具,主要是jcheckwebrevdefpath。这是一种让许多有经验的贡献者感到愉悦且高效的工作流程。因此,如果我们转向外部提供商,保留尽可能多的这种工作流程是至关重要的。

GitHub 和其他流行托管平台上的工作流程采用了 拉取请求(PR)的概念,从高层次上看,这与 OpenJDK 贡献者目前使用的请求审查(RFR)电子邮件类似。GitHub 上的贡献者会从一个源分支向特定仓库中的目标分支创建一个 PR(源分支和目标分支不必位于同一个仓库中)。然后,其他贡献者会对该 PR 进行审查,并根据评审反馈对源分支进行额外的提交。一旦评审者对更改感到满意,PR 就会被合并到目标分支中。

此 JEP 提议支持多种工作流,使用在 Project Skara 中开发的工具。贡献者可以选择最适合他们的任何工作流:

  • 基于 CLI 和邮件列表(类似于当前的工作流程)
  • 基于 Web 浏览器(通过 GitHub 网站)
  • 基于文本编辑器和 IDE(通过插件以及文本编辑器和 IDE 中的 GitHub 支持)
  • 基于 CLI(通过自定义 CLI 工具)

当然,可以混合和匹配不同的工作流程。在一个像 OpenJDK 这样庞大且多样化的开源社区中,各个贡献者的工作流程唯一的共同点就是它们各不相同。在描述各种工具和服务之前,我们先从一个引入新变更的工作流程示例开始。(有关更专门任务的工作流程,例如在存储库之间同步或添加标签,将在本 JEP 的未来修订版中讨论。)

工作流程

所有四种工作流程的共同点是,每个变更都从一个拉取请求(PR)开始。PR 可以通过多种方式创建 —— 从命令行界面(CLI)、网页浏览器、文本编辑器或集成开发环境(IDE)。然而,创建 PR 需要有一个 GitHub 账户。对于不希望在 GitHub 上创建账户的贡献者,我们仍会接受发送到 OpenJDK 邮件列表 的补丁。然而,这样的补丁需要由拥有 GitHub 账户的贡献者来创建一个 PR,这与当前许多贡献者帮助新人创建并上传 webrevs 到 cr 的方式类似。

创建 PR 后,PR 中的提交会由 jcheck 提交分析工具进行分析,该工具作为服务器端程序运行(所谓的“机器人”)。jcheck 机器人使用外部提供商的 API 根据提供商 API 的功能将潜在问题以评论或错误的形式展示出来。在 GitHub 上,jcheck 机器人特别利用 Checks API 来生成信息丰富的错误消息。jcheck 机器人可以通过仓库中的 .jcheck/config 配置文件进行配置。如果已配置,其中一项检查会确保所提议的更改在 JBS 中有相应的问题。在这种情况下,机器人会确保 PR 的标题与 JBS 问题的标题相对应,类似于 RFR 电子邮件的标题。如果 PR 的标题包含一个 JBS 问题,那么 jbs 机器人会在相应的 JBS 问题中添加一个指向该 PR 的 链接

一旦 PR 通过了 jcheck,它就会获得 "rfr" 标签。这向潜在的审查者表明,该 PR 现在已经准备好进行审查。(审查者参与一个甚至无法通过 jcheck 的更改是没有意义的。)此时,PR 还会根据 PR 中提交所更改的源代码区域自动添加标签。例如,一个针对 jdk 仓库 master 分支的 PR,如果同时更改了 make 目录和 src/hotspot 目录,则会获得 build-devhotspot-dev 标签。一封自动生成的 RFR 邮件会被发送到邮件列表 build-dev@openjdk.java.nethotspot-dev@openjdk.java.net,以及 PR 作者指定的任何其他邮件列表。RFR 邮件包含 PR 的标题和正文、PR 中提交的自动生成的摘要,以及指向自动生成的 webrevs 的链接。

评审人员现在可以使用多种工作流程来讨论 PR 中的变更:

  • 通过回复发送到邮件列表的 RFR 电子邮件,回复内容会被复制到 GitHub 上的 PR 中(不需要 GitHub 帐户);
  • 通过 Web 浏览器使用 https://github.com/ 上的审查工具;
  • 通过使用与 GitHub 集成的各种文本编辑器和 IDE 中的审查工具;
  • 通过使用与 GitHub 集成的图形桌面应用程序;或者
  • 通过使用 Skara CLI 工具。

任何工作流程中发表的评论都会反映在所有工作流程中。一位评审员可以通过邮件列表添加评论,另一位通过网页浏览器,第三位通过命令行,他们都将看到彼此的评论。

如果 PR 作者根据评审人员的反馈向源分支推送了额外的提交,那么一个机器人会回复 RFR 邮件,包含新提交的自动摘要以及自动生成的增量和完整 webrev。

由于评审者对更改感到满意,他们会将 PR 标记为已评审。可以采用以下方法进行:

  • 使用网页浏览器和 https://github.com/,
  • 使用命令行中的 git pr approve
  • 使用带有 GitHub 集成的文本编辑器和/或 IDE,或者
  • 使用带有 GitHub 集成的图形桌面工具。

一旦所有审查者都满意了,PR 的作者就可以最终整合该 PR。他们通过添加内容完全为 /integrate 的评论来实现这一操作,之后会发生一系列的事情:

  1. 一个机器人将所有提交压缩(合并)为一个提交。
  2. 如果有必要,一个机器人会在目标分支(通常是 master)之上对压缩后的提交进行变基。
  3. 一个机器人会为最终的提交构建提交信息,其中包括:
    • 将 PR 的标题作为提交信息的标题,
    • 基于 PR 中以 /summary 开头的评论生成正文,
    • Reviewed-by: 尾部添加所有评审人的 OpenJDK 用户名,以及
    • Co-authored-by: 尾部添加所有合作者。
  4. 一个机器人将生成的提交推送到目标分支(通常是 master)。

作者可以在实际整合 PR 之前预览发出 /integrate 命令的结果,包括提交信息。

如果 PR 的作者不是 OpenJDK Committer,则在作者在评论中发出 /integrate 命令后,会添加标签 sponsor。然后,一位 OpenJDK Committer 必须在新评论中输入 /sponsor 命令以合并该 PR。

权限和角色

正如前文所述,我们并不打算改变 OpenJDK 的Census,也不会基于外部源代码托管平台来建模 OpenJDK 贡献者的角色和权限。相反,服务器端工具(“bots”)会维护一个 OpenJDK 贡献者的 GitHub 用户 ID(不是用户名,因为用户名不稳定)到 OpenJDK 用户名的映射。这样,这些 bots 就可以检查,例如,某个 PR 的作者是否为 OpenJDK 的Author,或者某个 PR 的评审者是否为 OpenJDK 的Reviewer。此模型独立于外部提供商。这也意味着无需在外部提供商上复制 OpenJDK 的Census 数据。

工具

Skara 项目的贡献者开发了各种支持此 JEP 的工具,包括在贡献者计算机上本地运行的 CLI 工具和在提供商服务器上运行的服务器端工具(“机器人”)。CLI 工具主要用于帮助希望通过命令行与外部提供商交互的贡献者。这些工具包括:

  • git-fork:在外部提供商上 fork 一个项目并克隆它
  • git-pr:更新、批准、获取、显示等操作一个拉取请求
  • git-sync:从上游仓库同步分支
  • git-publish:将本地分支发布到远程仓库
  • git-info:从提交信息中提取 OpenJDK 特定的信息
  • git-token:与 Git 凭证管理器交互以处理令牌
  • git-proxy:通过 HTTP(S) 代理代理所有来自 Git 命令的网络流量
  • git-skara:学习关于 Skara CLI 工具并进行更新

以下 CLI 工具已经提供,以支持 JEP 357(从 Mercurial 迁移到 Git)

  • git-jcheck:在本地运行 jcheck
  • git-webrev:创建一个 webrev
  • git-defpath:设置推送和拉取路径
  • git-translate:在 hg 和 git 哈希之间进行转换

协助贡献者的机器人有:

  • pr:检查、标记并集成拉取请求
  • ml-bridge:在邮件列表和源代码托管服务之间桥接评论
  • notify:推送后向邮件列表发送通知
  • archiver:以 JSON 格式在 Git 仓库中存档所有 PR 元数据
  • forwarder:将推送的提交转发到其他仓库(例如,沙盒)
  • jbs:更新 JBS(类似于现有的 "hgupdater" 服务)
  • submit:作为机器人实现的测试服务示例

服务

除了这些机器人之外,还有两项服务可帮助贡献者和审核者:

  • OCA 服务减轻了审查人员检查贡献者是否签署了 Oracle Contributor Agreement 的负担。

  • 测试服务jdk/submit 仓库的通用版本。它允许贡献者在 PR 评论中发出 /test 请求,一个或多个测试服务可以对此进行响应。一个简单的测试服务示例已经以提交机器人(submit bot)的形式提供。

替代方案

  • 继续使用 Mercurial 和现有的 OpenJDK 工作流程。(对于像 JDK 这样庞大的代码仓库,我们预计使用 hg-git 或类似工具在客户端保留服务器端 Git 主仓库的 Mercurial 版本是不现实的。)

  • 使用 GitLab EE 作为外部源代码托管提供商。

  • 使用 BitBucket 作为外部源代码托管提供商。

测试

  • 几乎所有工作流程的场景都已在 Skara 项目中作为集成测试实现。

  • Skara 项目已经长时间将自己的代码使用所提议的工作流程。

  • 其他几个 OpenJDK 项目已将其存储库以评估为基础迁移到了 GitHub:OpenJFXLoomMobileOpenJMCPanamaMetropolisValhallaAmberTsanZGCLanai 以及部分 Code Tools 项目。这些项目对工具、机器人和服务进行了实际测试,以确保进一步的项目过渡可以以较低的摩擦完成。

风险与假设

切换到外部源代码托管提供商的主要风险是 OpenJDK 社区可能会对该提供商产生依赖性。由于 Git 的分布式特性,版本控制数据本身将始终独立于提供商。然而,像代码审查评论这样的元数据可能会被锁定在某个特定的提供商中,这是存在风险的。此外,工具和工作流程可能会对某个特定的提供商产生依赖性,从而导致由于工具中的假设而无法更换提供商。

减轻这些风险一直是 Skara 项目的主要关注点。以下设计决策确保关键元数据不会锁定到任何特定的提供商:

  • 拉取请求中的所有讨论都会复制到相应的 OpenJDK 邮件列表

  • 拉取请求中的所有讨论都会以两种格式存档:mbox(供人类阅读)和 JSON(供软件使用)。

  • 推送通知会发送到相应的 *-changes@openjdk.java.net 邮件列表,从而避免依赖于提供商的 RSS 源。

  • OpenJDK 人口普查 用于用户组织和权限级别,从而避免依赖于提供商的用户组织工具。

  • 域名 https://git.openjdk.java.net/ 会重定向到 OpenJDK 社区当前的源代码托管提供商。记录在 JBS 问题 和邮件列表消息中的源代码 URL 使用此域名,而不是当前提供商的域名。

为了防止 Skara 工具依赖于特定供应商的 API,从一开始支持多个外部供应商就是一个严格的要求。所有工具还必须与开源的 GitLab Community Edition(GitLab CE)一起使用。

依赖