简介
引言
我们欢迎并鼓励各种形式、各种层次的贡献,例如:
- 提交问题报告或功能请求的工单
- 参与讨论
- 改进文档
- 贡献代码,包括提交 PR 以及(尤其是)评审 PR。
除了提交新的 PR 之外,社区成员相互评审彼此的 PR 也是一项良好的传统。这样做不仅能帮助社区,还能让你更熟悉 Rust 以及相关的代码库。
开发环境
请先参阅开发环境快速入门。
寻找和创建可供着手处理的问题
你可以查阅精选的 good-first-issue 列表,以便开始上手。关于我们如何规划较大的项目,可以阅读路线图与改进提案部分。
开放贡献与工单分配
DataFusion 是一个开放贡献的项目,因此对于完成某个问题没有特定的项目期限限制,也不限制谁可以处理某个问题,更不限制同时可以有多少人处理同一个问题。
贡献者根据自己的优先级和兴趣推动项目前进,因此你可以自由处理任何你感兴趣的问题。
如果某个你想要或需要处理的问题已经有人在做,但尚未完成,你也可以自由地接手处理。一般来说,开始处理某个问题时在下面留言说明一声,既是一种礼貌,也有助于避免不必要的重复劳动。
如果你想处理的问题尚未分配给其他人,也没有评论表明已有人在处理,那么你只需发表一条单字评论 take,即可将该问题分配给自己。不过,如果你无法取得进展,就应该发表单字评论 untake 来取消分配。
开发者指南
Pull Request 概览
我们欢迎来自社区任何成员的 Pull Request(PR)。
DataFusion 是一个快速演进的项目,我们会尽量快速地评审并合并 PR。
评审带宽是我们目前最稀缺的资源,我们非常鼓励更广泛的社区参与评审。如果你正在等待自己的 PR 被评审,不妨考虑去帮助评审其他等待中的 PR。这样的评审既能帮助评审者学习代码库、成长为专家,也能帮助发现 PR 中的问题(例如测试覆盖不足),这些问题得到解决后,未来的评审会更快、更高效。
一个 PR 的生命周期如下:
- 创建一个以
main分支为目标的 PR。 - 对于新贡献者,必须先由一名 committer 触发 CI 任务。请在 PR 中 @ committers 列表中的成员,以帮助触发 CI。
- 你的 PR 将会收到评审。请对 PR 上的所有反馈作出回应:你不一定要修改代码,但应当确认已收到这些反馈。等待反馈超过几天的 PR 将被标记为草稿(draft)。
- 一旦 PR 获得批准,committers 中的某一位会合并你的 PR,通常在 24 小时内完成。已批准的「重大」(major)变更(见下文)会保留开放 24 小时后再合并,有时「次要」(minor)的 PR 也会保留同样长的时间,以便收集更多反馈。
请注意,上述时间范围只是估算。由于 committer 的带宽有限,合并你的 PR 可能需要更长时间。请耐心等待。如果已经过去好几天,你可以友好地提醒一下批准你 PR 的 committer,帮助他们记得合并。
创建 Pull 请求
在可能的情况下,我们建议将你的贡献拆分成多个更小、更聚焦的 PR,而不是大型 PR(500 行以上),原因如下:
- PR 更有可能被快速评审——我们的评审者很难抽出连续的时间来评审大型 PR。
- PR 的讨论往往更聚焦,也不太容易在多个不同话题串中被淹没。
- 当反馈在小改动的早期阶段到来时,通常更容易接受并据此行动,此时某个具体方案还没有被过度打磨。
如果你担心一个较大的设计会在一连串小 PR 中被割裂,可以创建一个大型的草稿 PR,展示这些改动如何协同工作。
请注意,PR 中的所有提交在合并到 main 分支时都会被压缩(squash),因此合并后每个 PR 只对应一个提交。
对于较大的 PR,在自己的 PR 上留一条评审评论、指出重要的改动或某些关键选择,通常很有帮助。这些标注可以帮助评审者快速找到应当重点关注的区域,从而加快评审进度。
发布管理与回移
面向贡献者的发布分支、补丁版本和回移(backport)相关指南,记录在发布管理指南中。
提交 PR 之前
在提交 PR 之前,请运行标准的非功能性检查。PR 必须通过这些检查才能合并。
./dev/rust_lint.sh
# use `--write` to automatically fix some formatting and lint errors
# ./dev/rust_lint.sh --write --allow-dirty你应当同时运行快速测试中的相关命令。
约定式提交与 PR 标签
我们通过自动化流程为每个版本生成变更日志,该流程会根据 PR 标题和/或附加到 PR 的 GitHub 标签对 PR 进行分类。
我们遵循约定式提交(Conventional Commits)规范,依据标题对 PR 进行分类。这通常只是查找以 fix:、feat:、docs: 或 chore: 等前缀开头的标题。我们并不强制要求遵循这一约定,但如果你希望自己的 PR 出现在变更日志的正确部分,建议采用这种写法。
变更日志生成器还会查看 bug、enhancement 或 api change 等 GitHub 标签,并且标签的优先级高于约定式提交的方式,这使维护者能够在 PR 合并之后重新对其分类。
审查拉取请求
关于我们在审查 PR 时关注的要点,以及如何为自己的 PR 做好审查准备,请参阅审查拉取请求指南。
性能改进
性能改进始终受到欢迎:性能是 DataFusion 的核心特性。
一般来说,一项变更带来的性能提升应当“足够”证明为此增加的代码复杂度是合理的。所谓“足够”由提交者(committer)判断,但通常意味着该提升在真实场景中应当是可感知的,并且大于基准测试系统的噪声。
为了帮助提交者评估潜在的改进,性能类 PR 通常应当附上能够证明该改进的基准测试结果。
展示性能改进的最佳方式是使用现有的基准测试:
- 系统级 SQL 基准测试
- 微基准测试,例如 functions/benches 中的测试
如果没有合适的现有基准测试,你可以创建一个新的。建议先用一个单独的 PR 提交基准测试,再用另一个 PR 提交改进该基准测试的代码变更,这样有助于隔离变更的效果。
“重大”与“次要” PR
由于我们是一个全球性社区,贡献者分布在许多时区进行审查和评论。为了确保任何希望参与的人都有机会审查 PR,我们的提交者会尽量保证从一个“重大(major)”PR 获得批准到被合并之间至少间隔 24 小时。
“重大”(major)PR 指设计上有重大变更或 API 发生变更。提交者(committer)会凭借自己的专业判断来决定何为重大变更。“次要”(minor)PR 可以不必等待 24 小时直接合并,同样取决于提交者的判断。潜在的“次要”PR 示例包括:
- 文档改进或补充
- 小型缺陷修复
- 无争议的构建相关改动(clippy、版本升级等)
- 无争议的小型功能增补
开源代码与开放开发的好处在于,某次变更中的问题几乎总能通过后续的 PR 加以修复。
陈旧的 PR
拉取请求在 60 天无活动后会被标记 stale 标签,并在再过 7 天后被关闭。在 PR 上发表评论即可移除 stale 标签。
AI 辅助贡献
DataFusion 针对 AI 辅助 PR 制定了如下政策:
- PR 作者应当端到端地理解实现背后的核心思想,并能够在评审过程中为设计和代码作出合理解释。
- 指出未知之处与假设。不完全理解 AI 生成代码的某些部分是可以接受的。你应当对这些情况加以评论并提示评审者,以便他们凭借对代码库的了解来消除疑虑。例如,你可以评论道:“在这里调用这个函数似乎能正常工作,但我不熟悉它内部的实现方式,我担心并发调用时是否存在竞态条件。”
为什么完全不加理解的 AI 生成 PR 没有帮助
目前,AI 工具无法可靠地独立完成对 DataFusion 的复杂修改,这也是我们依赖拉取请求和代码评审的原因。
代码评审的目的在于:
- 完成预期的任务。
- 在作者与评审者之间分享知识,这是对项目的长期投入。正因如此,即使熟悉代码库的人能很快完成任务,我们仍然乐于帮助新贡献者参与其中,即便这会花费更长时间。
针对某个问题倾倒一份 AI 输出无法达成上述目的。维护者直接使用 AI 可以更快地完成任务,而提交者如果仅作为 AI 的传声筒、不加理解地转手,自己也学不到多少东西。
请理解,本项目的评审资源非常有限,因此那些看起来缺乏必要理解的大型 PR 可能不会得到评审,最终会被关闭或被引导转向。
比“AI 倾倒”更好的贡献方式
建议撰写高质量的 issue,明确问题陈述,并附上最小化的可复现示例。这样可以让其他人更容易参与贡献。
CI 运行器
Runs-On
我们在主仓库中使用 Runs-On 执行部分 action,这些 action 运行在 ASF 的 AWS 账户中,以加快 CI 速度。在分叉仓库中,这些 action 会运行在默认的 GitHub 运行器上,因为分叉仓库无法访问 ASF 的基础设施。
配置时,我们使用以下格式:
runs-on: ${{ github.repository_owner == 'apache' && format('runs-on={0},family=m8a,cpu=16,image=ubuntu24-full-x64,extras=s3-cache,disk=large,tag=datafusion', github.run_id) || 'ubuntu-latest' }}
这是一个条件表达式:对主仓库使用 Runs-On 自定义运行器,对分叉仓库则回退到标准的 GitHub 运行器。Runs-On 的配置遵循 Runs-On 规范。
对于这些 action,我们还使用 Runs-On action,它支持外部缓存并上报作业指标:
- uses: runs-on/action@cd2b598b0515d39d78c38a02d529db87d2196d1e
对于标准的 GitHub 运行器,该 action 不会做任何事情。
竞价实例
默认情况下,Runs-On 的 action 以竞价实例运行,这意味着它们偶尔可能会被中断。在 CI 中你会看到:
Error: The operation was canceled.根据 Runs-On 的数据,运行时间少于 1 小时的实例几乎不会被 Spot 中断,即使被中断,这些作业也会自动重新启动。
GitHub 运行器
我们还在主仓库的部分作业中使用标准 GitHub 运行器;这些作业同样可以在 fork 中运行。
评论
登录后参与评论
KnowForge