跳到主要内容
在 GitHub 上编辑此页面

指南

Pull Request 指南

我们希望大力提倡的一种理念是

在创建 PR 之前,请先创建一个 issue。

目的是将问题与可能的解决方案分开。

Bug 修复: 如果你只是修复一个小的 bug,可以直接提交 Pull Request,但我们强烈建议你创建一个 issue 来详细说明你修复的内容。这在不接受特定修复但希望跟踪问题的情况下非常有用。请记住,项目维护者保留接受或拒绝传入 PR 的权利,因此最好将问题与修复它的代码分开。在某些情况下,项目维护者可能会要求你创建独立于 PR 的 issue 才能继续进行。

重构: 对于小的重构,它本身可以成为一个独立的 PR,详细说明你重构了什么以及为什么。如果有疑问,项目维护者可能会要求你为 PR 创建 #SIP 才能继续进行。

功能/重大变更: 如果你打算更改公共 API,或对实现进行任何非微不足道的更改,我们要求你创建一个新的 issue 作为 #SIP (Superset Improvement Proposal)。这使我们能够在你在投入大量精力之前就达成你的提议。你可以在 SIP 旁边提交一个 PR(有时为了演示需要),但我们不会在 SIP 被批准之前审查/合并代码。

总的来说,小 PR 总是比大 PR 更容易审查。最佳做法是将你的工作分解成更小的独立 PR 并参考同一个 issue。这将大大减少周转时间。

如果你希望分享你的工作,但它还没有准备好合并,可以创建一个 Draft PR。这将使维护者和 CI 运行器能够优先处理成熟的 PR。

最后,永远不要提交会导致 master 分支处于崩溃状态的 PR。如果 PR 是多个 PR 中的一部分以完成一个大的功能,并且无法独立工作,则可以在创建 PR 到 master 分支之前创建一个功能分支并将所有相关 PR 合并到功能分支中。

协议

撰写

  • 填写 PR 模板中的所有部分。

  • 使用以下语义前缀之一为 PR 命名(灵感来自 Karma

    • feat (新功能)
    • fix (Bug 修复)
    • docs (文档更改)
    • style (格式化、缺少分号等;无应用程序逻辑更改)
    • refactor (重构代码)
    • test (添加缺少的测试、重构测试;无应用程序逻辑更改)
    • chore (更新任务等;无应用程序逻辑更改)
    • perf (性能相关更改)
    • build (构建工具、Docker 配置更改)
    • ci (测试运行器、GitHub Actions 工作流程更改)
    • other (与以上不符的更改——应该很少见!)
    • 示例
      • feat: 将图表导出为 ZIP 文件
      • perf(api): 提高 API 信息性能
      • fix(chart-api): 缓存指标始终显示值为缓存
  • 如果尚未准备好审查,请在标题中添加前缀 [WIP](WIP = 工作进行中)。我们建议先创建一个带有 [WIP] 的 PR,并在通过 CI 测试并至少查看一次代码更改后将其删除。

  • 如果你认为你的 PR 贡献了潜在的破坏性更改,请在语义前缀后但在冒号之前在 PR 标题中添加一个 !,如下所示:feat!: Added foo functionality to bar

  • 屏幕截图/GIF: 对用户界面的更改需要前后屏幕截图,或用于交互的 GIF

    • 推荐的捕获工具 (KapLICEcapSkitch)
    • 如果没有提供屏幕截图,提交者将在 PR 上标记 need:screenshot 标签,并且在提供屏幕截图之前不会审查。
  • 依赖关系: 请注意添加新的依赖关系,并避免不必要的依赖关系。

    • 对于 Python,请将其包含在 pyproject.toml 中,并指定任何特定限制,并在 requirements.txt 中固定到特定版本,以确保应用程序构建是确定性的。
    • 对于 TypeScript/JavaScript,请将新的库包含在 package.json
  • 测试: Pull Request 应包含测试,可以是 doctests、单元测试或两者兼而有之。确保解决所有错误和测试失败。有关如何运行测试,请参阅 测试

  • 文档: 如果 Pull Request 添加了功能,则应在同一个 PR 中更新文档。

  • CI: 审查者在所有 CI 测试通过之前不会审查代码。有时可能存在不稳定的测试。你可以关闭并打开 PR 来重新运行 CI 测试。如果问题仍然存在,请报告。在 CI 修复已部署到 master 后,请重新整理你的 PR。

  • 代码覆盖率: 请确保代码覆盖率不会下降。

  • 准备好审查后,请删除 [WIP]。请注意,它可能会在批准后立即被合并,因此请确保 PR 准备好合并,并且不要指望在批准后有更多时间进行编辑。

  • 如果 PR 尚未准备好审查,并且在超过 30 天后仍处于非活动状态,我们将将其关闭。如果它没有任何状态标签,则添加 inactive

审查

  • 在撰写审查意见时,请使用建设性的语气。
  • 如果需要进行更改,请清楚说明在 PR 能够被批准之前需要完成哪些操作。
  • 如果你被要求使用一些更改来更新你的 Pull Request,则无需创建一个新的 Pull Request。将你的更改推送到同一个分支。
  • 提交者保留拒绝任何 PR 的权利,并且在某些情况下可能会要求作者创建一个 issue。

测试环境

  • Apache GitHub 组织的成员可以通过创建包含(仅)命令 /testenv up 的评论,直接在 Pull Request 上启动一个临时的测试环境。
    • 请注意,组织成员身份必须是公开的,才能使此验证正常工作。
  • 可以通过在命令后指定标志名称(以 FEATURE_ 为前缀)和值来设置测试环境的特性标志。
    • 格式: /testenv up FEATURE_<feature flag name>=true|false
    • 示例: /testenv up FEATURE_DASHBOARD_NATIVE_FILTERS=true
    • 可以在单个命令中设置多个特性标志,用空格分隔
  • 工作流程脚本将创建一个包含临时环境的地址和登录信息的评论。
  • 在 PR 的 Docker 构建 CI 工作流程成功完成之后,可以创建测试环境。
  • 测试环境目前不会在 Pull Request 中添加新的提交时自动更新。
  • 测试环境目前不支持异步工作者,但这已在计划之中。
  • 运行测试环境将在关闭 Pull Request 时关闭。

合并

  • 合并 PR 至少需要一个批准。
  • PR 通常会在合并之前保持打开状态至少 24 小时。
  • 在 PR 合并后,关闭相应的 issue(s).

合并后责任

  • 如果 PR 引入了新的问题,项目维护者可能会联系 PR 作者。
  • 如果发现严重问题,例如破坏 master 分支的 CI,项目维护者可能会撤销你的更改。

管理 issue 和 PR

为了处理不断涌现的 issue 和 PR,提交者会阅读 issue/PR 并用标签标记它们,以对它们进行分类,并帮助贡献者确定采取行动的地方,因为贡献者通常拥有不同的专业知识。

分类目标

  • 对于 issue: 分类、筛选 issue、标记作者所需的操作。
  • 对于 PR: 分类、标记作者所需的操作。如果 PR 准备好审查,则标记审查者所需的操作。

首先,添加 **分类标签(又称哈希标签)**。每个 issue/PR 必须有一个哈希标签(除了垃圾邮件条目)。以 # 开头的标签定义 issue/PR 类型

标签针对 issue针对 PR
#bugBug 报告Bug 修复
#code-quality描述代码、架构或生产力方面的问题重构、测试、工具
#feature新功能请求新功能实现
#refine提出改进建议,例如调整填充或优化 UI 样式,不包括新功能、Bug 修复和重构。改进建议的实现,例如调整填充或优化 UI 样式,不包括新功能、Bug 修复和重构。
#doc文档文档
#question故障排除:安装、本地运行、询问如何执行某些操作。稍后可以更改为 #bugN/A
#SIPSuperset 改进提议N/A
#ASF与 Apache 软件基金会政策相关的任务与 Apache 软件基金会政策相关的任务

然后根据需要添加其他类型的标签。

  • 描述性标签(又称点标签): 这些以 . 开头的标签描述 issue/PR 的详细信息,例如 .ui.js.install.backend 等。每个 issue/PR 可以有零个或多个点标签。
  • 需要标签: 这些标签具有模式 need:xxx,描述进行操作所需的工作,例如 need:rebaseneed:updateneed:screenshot
  • 风险标签: 这些标签具有模式 risk:xxx,描述采用操作的潜在风险,例如 risk:db-migration。目的是更好地了解影响并提高对需要更严格测试的 PR 的认识。
  • 状态标签: 这些标签描述状态(abandonedwontfixcant-reproduce 等)。被拒绝或在没有完成的情况下关闭的 issue/PR 应该有一个或多个状态标签。
  • 版本标签: 这些标签具有模式 vx.x,例如 v0.28。issue 上的版本标签描述了报告 Bug 的版本。PR 上的版本标签描述了将包含 PR 的第一个版本。

提交者也可以更新标题以反映 issue/PR 内容,如果作者提供的标题不够描述性。

如果 PR 通过了 CI 测试,并且没有任何 need: 标签,则它已准备好审查,请添加标签 review 和/或 design-review

如果 issue/PR 在超过 30 天后处于非活动状态,则将其关闭。如果它没有任何状态标签,则添加 inactive

在创建 PR 时,如果你希望将其包含在特定版本中,请使用版本标签标记它。例如,要将 PR 纳入 Superset 1.1 的考虑范围,请使用标签 v1.1

撤销指南

撤销导致 master 分支出现问题的更改是开发过程中的正常且预期的一部分。在开源社区中,更改的影响并非总是可以完全理解。考虑到这一点,在考虑撤销时,请记住以下几点

  • PR 作者的可用性: 如果原始 PR 作者或合并代码的工程师高度可用,并且可以在合理的时间范围内提供修复,则这将反对撤销。
  • 问题的严重性: master 上的问题有多严重?它是否阻止项目向前推进?是否对用户有影响?有多少比例的用户会遇到问题?
  • 被撤销更改的大小: 撤销单个小型 PR 的风险远低于撤销大型的多 PR 更改。
  • 被撤销更改的年龄: 撤销最近合并的 PR 比撤销旧的 PR 更为可接受。在旧的 PR 中发现的 Bug 不太可能导致广泛的严重问题。
  • 撤销固有的风险: 撤销是否会破坏关键功能?药物比疾病更危险吗?
  • 制定修复方案的难度: 对于具有明确解决方案的问题,实施和合并修复可能比撤销更可取。

如果你决定撤销是可取的,则执行撤销操作的贡献者有责任

  • 联系相关方: 应联系 PR 的作者和合并工作内容的工程师,并告知他们撤销情况。
  • 提供简明的复现步骤: 确保原始 PR 作者可以清楚地理解和复制该问题。
  • 将撤销操作提交代码审查: 撤销操作必须得到另一位提交者的批准。

设计指南

大小写指南

句子式大小写

在 UI 中对所有内容使用句子式大小写(除了这些 **)。

句子式大小写主要为小写。仅将第一个单词的首字母大写,以及其他需要大写的单词,例如

  • 专有名词。 产品中的对象被视为专有名词,例如仪表盘、图表、保存的查询等。专有功能名称,例如 SQL Lab、Preset Manager专有名词
  • 缩略词 (例如 CSS、HTML)
  • 在引用本身从句子式大小写中大写的 UI 标签时(例如页面标题 - 仪表盘页面、图表页面、保存的查询页面等)
  • 在 UI 中反映的用户输入。例如,用户为仪表盘标签命名

句子大小写与标题大小写: 标题大小写:“一只狗在巴黎散步” 句子大小写:“一只狗在巴黎散步”

为什么使用句子大小写?

  • 它通常被认为是最快的阅读方式
  • 它是区分普通名词和专有名词的最简单形式

如何提及 UI 元素

在撰写有关 UI 元素的文章时,请使用与 UI 中相同的字母大小写。

例如,如果一个输入字段的标签为“姓名”,则您将其称为“姓名输入字段”。类似地,如果一个按钮的标签为“保存”,则您可以将其称为“保存按钮”。

如果产品页面的标题为“设置”,您在写作中将其称为:“在“设置”页面上编辑您的个人信息”。

通常,产品页面将与其包含的对象具有相同的标题。在这种情况下,请将页面称为 UI 中的显示方式,并将对象称为普通名词

  • 在“仪表盘”页面上上传仪表盘
  • 转到“仪表盘”
  • 查看仪表盘
  • 查看所有仪表盘
  • 在“CSS 模板”页面上上传 CSS 模板
  • 您保存的查询将显示在“已保存的查询”页面上
  • 在 SQL Lab 中创建自定义查询,然后创建仪表盘

句子大小写的例外情况

  • 输入标签、按钮和 UI 选项卡全部大写
  • 用户输入值(例如,列名、SQL Lab 选项卡名称)应保持其原始大小写

编程语言约定

Python

config.py 中的参数(可以通过 Flask app.config 字典访问)被假定为始终已定义,因此应通过以下方式直接访问,

blueprints = app.config["BLUEPRINTS"]

而不是,

blueprints = app.config.get("BLUEPRINTS")

或类似方式,因为后者会导致类型问题。前者是 List[Callable] 类型,而后者是 Optional[List[Callable]] 类型。

类型提示 / 类型提示

为了确保清晰度、一致性、可读性,所有新函数都应使用类型提示并包含文档字符串。

根据PEP-484,没有提出用于显式列出引发的异常的语法,因此建议将此信息放入文档字符串中,即

import math
from typing import Union


def sqrt(x: Union[float, int]) -> Union[float, int]:
"""
Return the square root of x.

:param x: A number
:returns: The square root of the given number
:raises ValueError: If the number is negative
"""

return math.sqrt(x)

TypeScript

TypeScript 得到完全支持,并且是编写所有新前端组件的推荐语言。在修改现有函数/组件时,迁移到 TypeScript 是值得赞赏的,但不是必需的。在#9162#9180 中可以找到将函数/组件迁移到 TypeScript 的示例。