SSWG 孵化流程
概览
正如服务器页面所述,Swift 服务器工作组 (SSWG) 的目标是为使用 Swift 进行服务器应用程序开发创建强大、健康的生态系统。实现此目标的一种途径是鼓励开发高质量、维护良好的库和工具,以便社区可以放心地依赖它们。
SSWG 和 Swift 演进流程之间的区别在于,作为工作组努力成果而产生的面向服务器的库和工具将存在于 Swift 语言项目本身之外,并且它们将分布在不同的代码库中。
Apple 和 Vapor 团队的工程师将积极参与此类库和工具的开发,我们非常希望看到社区加入这项工作。为此,工作组定义并启动了一个孵化流程,任何人都可以在其中提出、提议、开发和贡献此类库和工具。
孵化流程旨在帮助培育和成熟项目,确保标准化、质量和持久性。它还力求提高可能为 SSWG 使命增加价值的想法、实验或其他早期工作的可见性。以下文档详细介绍了此孵化流程。SSWG 指导小组的角色类似于 Swift 核心团队,并将根据社区的反馈,对推动提案/提议通过孵化流程做出最终决定。就像 Swift 演进一样,任何人都可以提出提案和提议,成为 SSWG 指导小组的成员绝不是一项要求。
流程
孵化分为以下阶段:推介 (Pitch)、提案 (Proposal)、开发 (Development) 和 推荐 (Recommendation)。“开发”阶段是孵化过程的主要部分。SSWG 将维护一个公开的“Swift 服务器生态系统”索引页面,其中将列出所有推荐的工具和库,以及正在孵化过程中的项目及其各自的孵化级别。
推介 (Pitch)
推介是介绍新库或工具想法的引言。它们还可以介绍对现有工具的新功能或更改的想法。推介用于收集社区的反馈,并帮助在编写代码之前定义项目的确切范围。它们应展示如何与 SSWG 改善服务器端 Swift 的目标保持一致。推介通过在 Swift 服务器论坛区域中创建一个新主题来提交。
提案 (Proposal)
为了使推介进入提案阶段,它必须得到至少两名 SSWG 成员的认可。拟议代码的范围需要与认可的推介密切一致,并且要根据下面定义的 SSWG 毕业标准进行审查。
提案通过创建 PR 提交给 SSWG,该 PR 将提案文档添加到提案目录。提案遵循模板,并包含以下信息
- 名称(在 SSWG 内必须唯一)
- 描述(它做什么,为什么有价值,起源和历史)
- 关于与 SSWG 使命一致性的声明
- 首选的初始成熟度级别(请参阅 SSWG 毕业标准)
- 初始提交者(从事项目工作多长时间)
- 源代码链接(默认 GitHub)
- 外部依赖项(包括许可证)
- 发布方法和机制
- 许可证(默认 Apache 2)
- 问题跟踪器(默认 GitHub)
- 沟通渠道(Slack、IRC、邮件列表)
- 网站(可选)
- 社交媒体帐户(可选)
- 社区规模和任何现有赞助(可选)
一旦提案 PR 提交,SSWG 将在其双周会议期间分配一名审查经理。审查经理的职责包括
- 审查 PR
- 验证结构和语言。
- 确保实现已到位。
- 更新 PR
- 分配一个编号。
- 分配一名审查经理。
- 将状态设置为“正在审查 + 审查日期范围”
- 获得 PR 作者的批准以合并以上更改并合并它们。
- 在服务器提案区域发布论坛帖子,征求社区的反馈。
- 关注论坛主题中是否有不当行为或跑题问题,并确保作者参与其中。
- 审查期结束后,以书面形式向 SSWG 总结主要要点。
SSWG 以双周为周期对待审提案进行投票,目标是每月至少对两个提案进行投票。
投票结束后,审查经理将
- 在审查主题中宣布投票结果。
- 根据投票结果更新提案的状态。
- 关闭审查主题。
毕业标准
每个 SSWG 项目都有相关的成熟度级别:沙箱 (Sandbox)、孵化中 (Incubating) 或 已毕业 (Graduated)。提案应说明其首选的初始成熟度级别,SSWG 将进行投票以决定实际级别。
项目要被接受为“孵化中”或“已毕业”,需要获得绝对多数(三分之二)的票数。如果进入“已毕业”级别没有获得绝对多数票,则投向“已毕业”的票数将重新计为进入“孵化中”级别的票数。如果进入“孵化中”级别没有获得绝对多数票,则所有票数将重新计为进入“沙箱”级别的赞助。如果至少没有两位赞助者,则提案将被拒绝。
沙箱级别
要被沙箱级别接受,项目必须满足下面详述的SSWG 最低要求,并获得至少两位 SSWG 赞助者的认可。
早期采用者应格外谨慎地对待早期阶段的项目。虽然沙箱项目可以安全试用,但预计某些项目可能会失败,并且永远不会进入下一个成熟度级别。不保证生产就绪性、用户或专业级别的支持。因此,用户必须运用自己的判断力。
孵化中级别
要被孵化中级别接受,项目必须满足沙箱级别要求,外加
- 证明它已被至少两家独立的最终用户成功地用于生产环境,SSWG 判断这些最终用户的质量和范围足够。
- 必须有 2 名或更多维护者和/或提交者。在此上下文中,提交者是指被授予代码库写入权限并积极编写代码以添加新功能和修复任何错误和安全问题的个人。维护者是指有权访问代码库并积极审查和管理来自项目社区其余部分的贡献的个人。在所有情况下,代码在发布之前应至少由另一人审查。
- 软件包必须有多人拥有管理员访问权限。这是为了避免丢失对任何软件包的访问权限。对于托管在 GitHub 和 GitLab 上的软件包,这些软件包必须位于至少有两名管理员的组织中。如果您不想为软件包创建组织,则可以将它们托管在Swift Server Community组织中。
- 证明持续不断的提交和合并贡献的流程,或及时解决的问题,或类似的活动迹象。
- 获得 SSWG 的绝对多数票,以进入孵化阶段。
已毕业级别
要被已毕业级别接受,项目必须满足下面详述的SSWG 毕业要求,外加
- 证明它已被至少三家独立的最终用户成功地用于生产环境,SSWG 判断这些最终用户的质量和范围足够。
- 拥有来自至少两个组织的提交者和维护者,如上定义。
- 获得 SSWG 的绝对多数票,以进入毕业阶段。
流程图
生态系统索引
所有项目及其各自的级别都将列在Swift 服务器生态系统索引中。如果多个项目解决了特定问题(例如,两个类似的数据库驱动程序),它们将按受欢迎程度排序。SSWG 保留为关键构建块(例如,日志记录或指标 API)定义单一解决方案的权利,在这种情况下,跨生态系统的一致性至关重要。
建议已被任何成熟度级别接受的项目在其项目的 README 中列出成熟度级别,并带有定义的相应徽章
SSWG 将每 6 个月召开一次会议以审查所有项目,并且保留降级、存档或删除不再满足最低要求的项目的权利。例如,不再定期更新或未能及时解决安全问题的“已毕业”项目。同样,SSWG 保留删除或存档不再更新的推介和提案的权利。
对 Swift 服务器生态系统索引页面的更改将由 SSWG 使用 Swift 服务器论坛宣布。
最低要求
- 通用
- 与服务器端 Swift 具体相关
- 公共可访问的源代码,由 SCM(例如 github.com 或类似平台)管理
- 首选使用
main
作为默认分支名称,与 Swift 指南保持一致
- 首选使用
- 采用Swift 行为准则
- 生态系统
- 使用 SwiftPM
- 与关键的 SSWG 生态系统构建块集成,例如,日志记录和指标 API、用于 IO 的 SwiftNIO
- 持久性
- 必须来自拥有多个公共存储库的团队(或类似的经验迹象)
- 在紧急情况下,SSWG 应具有对已毕业存储库的访问/授权
- 采用SSWG 安全最佳实践
- 测试、CI 和发布
- 具有 Linux 的单元测试
- CI 设置,包括测试 PR 和主分支
- 遵循语义版本控制,至少发布一个预发布版本(例如 0.1.0、1.0.0-beta.1)或发布版本(例如 1.0.0)
- 许可
- Apache 2、MIT 或 BSD(推荐 Apache 2)
- 约定和风格
- 采用Swift API 设计指南
- 在适用时遵循SSWG 技术最佳实践。
- 首选采用代码格式化工具并将其集成到 CI 中
毕业要求
- 最低要求
- 拥有稳定的 API(没有待定/计划中的 API 破坏性更改),并且至少发布一个主要版本(例如 1.0.0)
- 在 30 天内支持 Swift 的新 GA 版本
- 为 推荐的两个最新 Swift 版本设置 CI
- 为至少一个 推荐的 Linux 发行版设置 CI
- 为库或工具支持的每个平台设置 CI
- macOS 和 Linux 的单元测试
- 在适当的时候使用 docker 镜像
- 文档化的发布方法
- 至少一个先前主要版本的文档化支持策略。
- 明确定义项目治理和提交者流程,最好分别在 GOVERNANCE.md 和 OWNERS.md 文件中列出
- 包含至少主要仓库的采用者列表,最好在 ADOPTERS.md 文件中列出或在项目网站上显示徽标
- 可选地,拥有开发者原创证书或贡献者许可协议
安全性
请遵循安全性部分中列出的指南。
技术最佳实践
- 在适当的情况下,优先使用原生 Swift 而不是 C 封装
- 并发 / IO
- 软件包应为非阻塞的(带有异步 API),除非不可能(阻塞式 C 库等)
- 应尽可能少(最好是没有)封装 NIO。直接公开 NIO 类型将大大有助于使软件包兼容。
- 阻塞代码应包装在 NIOThreadPool 中(如 Vapor 的 SQLite 软件包)
- 仅在前提条件时使用强制解包和强制 try,即程序员认为是不可避免的条件或程序员错误。所有强制 try/解包都应附带评论说明原因
- 除非与 C 接口,否则不使用
*Unsafe*
- 当适当地记录了为什么它们绝对必要时,使用
*Unsafe*
构造的例外情况是可以接受的。 - 当以这种方式使用
*Unsafe*
时,希望附带针对 Swift、SwiftNIO 或其他有问题的库中根本原因的增强请求工单。
- 当适当地记录了为什么它们绝对必要时,使用
- 避免使用
fatalError
来处理错误情况,设计throws
或返回Result
的 API。
变更管理
对孵化过程的更改必须记录在案并公开,并且受语义版本控制方案的约束
- 主要版本:表示方法或工作流程的更深层次的更改
- 次要版本:概念或命名法上的小变化。
导致版本号增加的更新需要 SSWG 的绝对多数投票。琐碎的更改,例如修复拼写错误或格式错误,不需要版本号增加。