指南
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
-
依赖关系: 请注意添加新的依赖关系,并避免不必要的依赖关系。
- 对于 Python,请将其包含在
pyproject.toml
中,并指定任何特定限制,并在requirements.txt
中固定到特定版本,以确保应用程序构建是确定性的。 - 对于 TypeScript/JavaScript,请将新的库包含在
package.json
中
- 对于 Python,请将其包含在
-
测试: 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 |
---|---|---|
#bug | Bug 报告 | Bug 修复 |
#code-quality | 描述代码、架构或生产力方面的问题 | 重构、测试、工具 |
#feature | 新功能请求 | 新功能实现 |
#refine | 提出改进建议,例如调整填充或优化 UI 样式,不包括新功能、Bug 修复和重构。 | 改进建议的实现,例如调整填充或优化 UI 样式,不包括新功能、Bug 修复和重构。 |
#doc | 文档 | 文档 |
#question | 故障排除:安装、本地运行、询问如何执行某些操作。稍后可以更改为 #bug 。 | N/A |
#SIP | Superset 改进提议 | N/A |
#ASF | 与 Apache 软件基金会政策相关的任务 | 与 Apache 软件基金会政策相关的任务 |
然后根据需要添加其他类型的标签。
- 描述性标签(又称点标签): 这些以
.
开头的标签描述 issue/PR 的详细信息,例如.ui
、.js
、.install
、.backend
等。每个 issue/PR 可以有零个或多个点标签。 - 需要标签: 这些标签具有模式
need:xxx
,描述进行操作所需的工作,例如need:rebase
、need:update
、need:screenshot
。 - 风险标签: 这些标签具有模式
risk:xxx
,描述采用操作的潜在风险,例如risk:db-migration
。目的是更好地了解影响并提高对需要更严格测试的 PR 的认识。 - 状态标签: 这些标签描述状态(
abandoned
、wontfix
、cant-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 的示例。