跳到主要内容
版本 下一

指南

拉取请求指南

我们强烈鼓励的理念是

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

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

Bug 修复:如果您只是修复一个小 Bug,可以直接提交拉取请求,但我们强烈建议您提交一个详细说明您正在修复内容的 Issue。这有助于我们在不接受特定修复但希望跟踪问题的情况下。请记住,项目维护者保留接受或拒绝传入 PR 的权利,因此最好将 Issue 和修复代码彼此分开。在某些情况下,项目维护者可能会要求您在继续之前从 PR 创建一个单独的 Issue。

重构:对于小型重构,它可以是独立的 PR,详细说明您正在重构什么以及为什么。如果存在疑虑,项目维护者可能会要求您在继续之前为 PR 创建一个 #SIP

功能/大型更改:如果您打算更改公共 API,或对实现进行任何非平凡的更改,我们要求您提交一个新 Issue 作为 #SIP(Superset 改进提案)。这使我们能够在您投入大量精力之前就您的提案达成一致。欢迎您随 SIP 一起提交 PR(有时出于演示目的有必要),但在 SIP 获得批准之前,我们不会审查/合并代码。

通常,小型 PR 总是比大型 PR 更容易审查。最佳实践是将您的工作分解为更小的独立 PR,并引用相同的 Issue。这将大大减少周转时间。

如果您希望分享尚未准备好合并的工作,请创建一个草稿 PR。这将使维护者和 CI 运行程序能够优先处理成熟的 PR。

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

协议

撰写

  • 填写 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): cached-indicator 始终显示值为已缓存
  • 如果未准备好审查,请在标题中添加前缀 [WIP] (WIP = work-in-progress)。我们建议先创建带有 [WIP] 的 PR,并在通过 CI 测试并至少通读一次代码更改后将其删除。

  • 如果您认为您的 PR 带来了潜在的破坏性更改,请在 PR 标题中的语义前缀之后但在冒号之前添加 !,例如:feat!: 为 bar 添加了 foo 功能

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

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

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

  • 文档:如果拉取请求添加了功能,则应在同一 PR 中更新文档。

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

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

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

  • 如果 PR 未准备好审查且不活动超过 30 天,我们将因不活动而关闭它。作者可以重新打开并更新。

审查

  • 撰写评论时使用建设性的语气。
  • 如果需要更改,请清楚说明在批准 PR 之前需要做什么。
  • 如果您被要求更新您的拉取请求并进行一些更改,则无需创建新的拉取请求。将您的更改推送到同一个分支。
  • 提交者保留拒绝任何 PR 的权利,在某些情况下可能会要求作者提交 Issue。

测试环境

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

合并

  • 合并 PR 至少需要一次批准。
  • PR 通常会在合并前保持开放至少 24 小时。
  • PR 合并后,关闭相应的 Issue

合并后责任

  • 如果 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故障排除:安装、本地运行、询问如何操作。稍后可以更改为 #bug不适用
#SIPSuperset 改进提案不适用
#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 中的用户输入。例如,用户命名的仪表板选项卡

句子大小写与标题大小写:标题大小写:“A Dog Takes a Walk in Paris”(狗在巴黎散步) 句子大小写:“A dog takes a walk in Paris”(一只狗在巴黎散步)

为什么使用句子大小写?

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

如何提及 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]] 类型。

类型/类型提示

为确保清晰、一致和可读性,所有新函数都应使用类型提示并包含 docstring。

请注意,根据PEP-484,没有明确列出引发异常的语法,因此建议将此信息放在 docstring 中,即,

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,但不是必需的。将函数/组件迁移到 TypeScript 的示例可以在#9162#9180中找到。