44/C4

44/C4

集体代码构建契约

集体代码构建契约 (C4) 是 github.com Fork + Pull 模型 的演进,旨在为自由软件项目提供最佳的协作模式。这是 C4 规范的第 3 版,并废弃了 RFC 42。

许可证

版权所有 (c) 2009-2016 Pieter Hintjens。版权所有 (c) 2016-2018 ZeroMQ 开发者。

本规范是自由软件;您可以根据自由软件基金会发布的 GNU通用公共许可证 的条款重新分发和/或修改它;许可证的第 3 版,或者(根据您的选择)任何更新的版本。

分发本规范是希望它有所帮助,但没有任何担保;甚至不包括适销性或特定用途适用性的默示担保。更多详情请参阅 GNU通用公共许可证。

您应该已随本程序收到一份 GNU通用公共许可证 的副本;如果未收到,请访问 https://gnu.ac.cn/licenses

摘要

C4 提供了一套标准流程,用于软件项目的贡献、评估和改进讨论。它定义了项目的特定技术要求,例如代码风格指南、单元测试、git 及类似平台。它还为项目建立了不同的角色,并明确区分了职责。C4 规定了问题记录和讨论的流程,包括寻求共识和清晰描述,使用“拉取请求”以及系统评审。

语言

本文档中的关键词 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL” 将根据 RFC 2119 中所述进行解释。

1. 目标

C4 旨在为开源软件项目提供可复用的最佳协作模型。它具有以下特定目标:

  1. 通过减少新贡献者的摩擦,并创建一个具有强大正反馈的规模化参与模型,从而最大化项目社区的规模和多样性;
  2. 通过分离不同的技能集,减轻对关键个人的依赖,从而在任何所需领域拥有更大的能力库;
  3. 通过增加决策过程的多样性,使项目能够更快、更准确地发展;
  4. 通过允许安全实验、快速失败和隔离稳定代码,支持项目版本从实验到稳定的自然生命周期;
  5. 降低项目仓库的内部复杂性,从而使贡献者更容易参与并减少出错范围;
  6. 强制项目的集体所有权,这增加了对贡献者的经济激励,并降低了被敌对实体劫持的风险。

2. 设计

2.1. 前提

  1. 项目 SHALL 使用 git 分布式版本控制系统。
  2. 项目 SHALL 托管在 github.com 或等效平台上,本文中称之为“平台”。
  3. 项目 SHALL 使用平台的问题跟踪器。
  4. 项目 SHOULD 有清晰记录的代码风格指南。
  5. “贡献者”是指希望提供补丁的人,补丁是解决某个已明确识别问题的提交集合。
  6. “维护者”是指将补丁合并到项目的人。维护者不是开发者;他们的工作是执行流程。
  7. “管理员”是指管理维护者集合的人。他们本身也是维护者。
  8. “创始人”是指创建项目和/或在某种意义上是精神所有者的人。
  9. 贡献者 SHALL NOT 拥有对仓库的提交权限,除非他们同时也是维护者。
  10. 维护者 SHALL 拥有对仓库的提交权限。
  11. 管理员 SHALL 拥有平台上的管理权限。
  12. 根据本契约条款,任何人,无论区别或歧视,SHALL 拥有成为贡献者的平等权利。

2.2. 许可与所有权

  1. 项目 SHALL 使用共享许可(share-alike license),例如 MPLv2,或 GPLv3 的变体(GPL、LGPL、AGPL)。
  2. 所有对项目源代码(“补丁”)的贡献 SHALL 使用与项目相同的许可。
  3. 所有补丁均归其作者所有。SHALL NOT 有任何版权转让流程。
  4. 每个贡献者 SHALL 负责在项目贡献者列表中表明身份。

2.3. 补丁要求

  1. 维护者和贡献者 MUST 拥有平台账户,且 SHOULD 使用其真实姓名或常用别名。
  2. 补丁 SHOULD 是针对一个已识别并已同意的问题的最小且准确的解决方案。
  3. 如果项目定义了代码风格指南,补丁 MUST 遵守。
  4. 补丁 MUST 遵守下方定义的“公共契约的演进”指南。
  5. 补丁 SHALL NOT 包含来自其他项目的非平凡代码,除非贡献者是该代码的原始作者。
  6. 补丁 MUST 在至少主要目标平台干净编译并通过项目自测。
  7. 补丁的提交消息 MUST 包含一行简短(少于 50 个字符)的文字,说明正在解决的问题(“Problem: …”),后接一个空行,然后是提议的解决方案(“Solution: …”)。
  8. “正确补丁”是满足上述要求的补丁。

2.4. 开发流程

  1. 项目上的变更 SHALL 受准确识别问题并应用最小、准确解决方案的模式支配。
  2. 要请求变更,用户 SHOULD 在项目平台的问题跟踪器上记录一个问题。
  3. 用户或贡献者 SHOULD 通过描述他们面临或观察到的问题来撰写该问题。
  4. 用户或贡献者 SHOULD 寻求对其观察的准确性以及解决该问题的价值的共识。
  5. 用户 SHALL NOT 记录功能请求、想法、建议或任何未明确记录且不可证明的问题解决方案。
  6. 因此,项目的发布历史 SHALL 是一个记录并解决的有意义问题列表。
  7. 要处理问题,贡献者 SHALL Fork 项目仓库,然后在他们 Fork 的仓库上工作。
  8. 要提交补丁,贡献者 SHALL 创建一个平台拉取请求回到项目。
  9. 贡献者 SHALL NOT 直接提交变更到项目。
  10. 如果平台将拉取请求作为问题实现,贡献者 MAY 直接发送拉取请求而无需另外记录问题。
  11. 要讨论补丁,人们 MAY 在平台拉取请求、提交或别处评论。
  12. 要接受或拒绝补丁,维护者 SHALL 使用平台界面。
  13. 维护者 SHOULD NOT 合并自己的补丁,除非在特殊情况下,例如其他维护者在较长时间(超过 1-2 天)内没有响应。
  14. 维护者 SHALL NOT 对正确补丁进行价值判断。
  15. 维护者 SHALL 快速合并来自其他贡献者的正确补丁。
  16. 维护者 MAY 合并来自其他贡献者的不正确补丁,其目标是 (a) 结束无果的讨论,(b) 将有害补丁记录在历史记录中,(c) 与贡献者互动以提高其补丁质量。
  17. 创建问题的用户 SHOULD 在检查补丁成功后关闭该问题。
  18. 任何对补丁有价值判断的贡献者 SHOULD 通过他们自己的补丁来表达这些判断。
  19. 维护者 SHOULD 关闭长时间(令人不适的一段时间)未采取行动而被搁置的用户问题。

2.5. 分支与发布

  1. 项目 SHALL 拥有一个分支(“main”,或历史上称为 “master”),该分支始终包含最新的开发中版本,并且 SHOULD 始终能构建。
  2. 项目 SHALL NOT 出于任何原因使用主题分支(topic branches)。个人 Fork MAY 使用主题分支。
  3. 要创建稳定发布,维护者 SHALL 标记仓库。稳定发布 SHALL 始终从仓库的 master 分支发布。

2.6. 公共契约的演进

  1. 所有公共契约(API 或协议及其行为和副作用)SHALL 被记录。
  2. 所有公共契约 SHOULD 具有可扩展性和实验空间。
  3. 修改稳定公共契约的补丁 SHOULD 不破坏现有应用程序,除非对于这样做的价值有压倒性的共识。
  4. 引入新功能的补丁 SHOULD 使用新名称(一个新契约)来完成。
  5. 新契约 SHOULD 在稳定并被实际用户使用之前标记为“草案”。
  6. 旧契约 SHOULD 通过将其标记为“已弃用”并根据需要用新契约替换来系统地弃用。
  7. 经过足够的时间后,已弃用的旧契约 SHOULD 被移除。
  8. 旧名称 SHALL NOT 被新契约重复使用。
  9. 标记为“草案”的新契约 MUST NOT 被更改为“稳定”,直到满足以下所有条件:
    1. 文档已编写且与可比契约一样全面。
    2. 行使功能的自测在主要目标平台通过。
    3. 契约在至少一次公开发布中未发生变化。
    4. 契约在至少 6 个月内未发生变化。
    5. 新契约及其实现的贡献者对状态变更没有否决。
  10. 标记为“草案”的新契约在满足上述条件时 SHOULD 更改为“稳定”。
  11. 新契约的“草案”到“稳定”的转换状态 SHOULD 使用平台的问题跟踪器进行跟踪。

2.7. 项目管理

  1. 项目创始人 SHALL 担任管理员,管理项目维护者集合。
  2. 管理员 SHALL 通过提拔最有效的维护者来确保其自身的继任。
  3. 作出正确补丁、清晰理解项目目标和流程的新贡献者 SHOULD 被邀请成为维护者。
  4. 管理员 SHOULD 移除长期不活跃或多次未能准确执行此流程的维护者。
  5. 管理员 SHOULD 阻止或禁止给项目中的他人造成压力和痛苦的“不良行为者”。这应该在公开讨论后进行,所有各方都有发言的机会。不良行为者是指反复无视项目规则和文化、无谓地好辩或怀有敌意、或具有冒犯性,并且在他人要求时无法自我纠正其行为的人。

延伸阅读

  • Argyris 的模型 1 和 2 - C4 的目标与 Argyris 的模型 2 一致。

  • 丰田 Kata - 涵盖了改进 Kata(一次解决一个问题)和指导 Kata(帮助他人学习改进 Kata)。

实现