OpenFaaS 贡献指南深度解读:Commit 规范、Go 测试实践与社区治理全解析

原创2026-09-19 10:36:231,415 阅读
文章标签:后端云原生微服务

OpenFaaS 贡献指南深度解读:Commit 规范、Go 测试实践与社区治理全解析

本文以仓库根目录的 CONTRIBUTING.md 为骨架,系统拆解 OpenFaaS(Serverless Functions Made Simple)社区贡献的完整流程:从功能提案、Commit 消息规范、Go 单元测试风格到 DCO 签署与维护者治理结构。无论你是想提交第一个 PR、写一个样例函数、评审他人代码,还是深入理解这个 Golang 开源项目的运作机制,都能在这里找到可直接落地的操作清单,并看到仓库源码(.DEREK.yml、gateway/go.mod、gateway/handlers/*_test.go 等)对这些规范的逐一印证。

适用范围与版本边界:这份指南管什么

首先要明确 CONTRIBUTING.md 的适用范围。这份指南针对 OpenFaaS Community Edition(CE)与 faasd 组件 的社区贡献;而 OpenFaaS Standard 与 OpenFaaS for Enterprises 是商业软件,仅由 OpenFaaS Ltd 员工独立维护,不在社区贡献范围内。商业客户的反馈走客户专属通道(openfaas/customers 仓库),普通用户则通过 GitHub Issues 与社区渠道互动。

这一点与仓库根目录 README.md 中的表述一致:本仓库属于 OpenFaaS CE,面向个人探索与爱好者用途,商业 PoC 有试用期限制,商用与生产负载需要 OpenFaaS Standard 或 OpenFaaS for Enterprises 许可证。许可证细节可分别查看 EULA.md(CE)与 pro/EULA.md(商业版)。

进入社区的第一步:自我介绍与用例

OpenFaaS 社区由志愿者构成,良好的第一印象是获得关注与帮助的前提。文档给出了一条可复用的自我介绍模板:

"We at Company Y have an issue with X, and would like some help. What we're trying to achieve is Z"

(我们公司在 Y 场景遇到 X 问题,希望能获得帮助,我们的目标是 Z。)

其要点是提供尽可能多的上下文:你是谁、你的兴趣/动机、你期望的理想结果。如果你是爱好者或学生,也请主动说明,这有助于社区对大量请求进行优先级排序。

文档同时点出一个典型反面教材:

"We are running into issue X. Can you fix it?" "We also had this issue"

这类提问以代词 "we" 开头,缺乏任何上下文与关系,在社区眼里是一份"匿名请求"。修复方式很简单:说清身份、兴趣与预期结果。

社区的两条主要互动通道是 GitHub Issues(用于疑似 Bug 与功能请求,需完整填写模板;性能/压测/调优类问题不通过 Issues 提问,属于专业服务范畴)与 企业支持通道。此外还有每周一次的社区 Zoom 电话会,任何免费用户或客户都可参加。

我能以哪些方式参与?

文档列出了大量贡献形式,并强调"这只是一小部分想法":

  • 为 CLI、Gateway 或其他 provider 编写 Go 代码
  • 为前端 UI(JS、HTML、CSS)开发功能
  • 用任意语言编写样例函数(参见 sample-functions 目录)
  • 评审 Pull Request
  • 测试新特性或进行中的工作(WIP)
  • 参与设计评审与技术 PoC
  • 协助发布与打包:Helm chart、compose 文件、kubectl YAML、应用市场与商店
  • 管理、分类与调研 Issues 和 Pull Requests
  • 在 GitHub 上为社区提供技术支持
  • 撰写文档、指南与博客
  • 在 meetup 或会议上演讲

从仓库结构看,可贡献的代码面也很直观:gateway 是核心 Go 模块(含 handlers、scaling、metrics、requests 等子包),gateway/assets 下是 AngularJS 前端 UI 与模板,api-docs/spec.openapi.yml 是 OpenAPI 规范(Makefile 中的 generate 目标即由该规范生成 Go models)。无论代码还是非代码贡献都有入口。

GitHub 贡献流程全解

发现安全问题

遵循负责任披露(responsible disclosure)实践,发送邮件至 support@openfaas.com。关键一点:复现步骤是证明问题存在并推动解决的核心,务必在邮件中给出。

修正文档错别字

一个字符级别的修正不需要 PR:直接在仓库 Issues 提交一个 Issue 即可,维护者会尽快修复。

功能提案:先讨论,后编码

OpenFaaS 维护者欢迎符合项目目标的提案,但强烈反对"先做完再提案"——已经完成的工作很难被客观评估,这违背项目精神。每个功能都有成本:开发错误的成本、长期维护的成本,以及"根本不需要"的沉没成本(文档援引 Martin Fowler 的 YAGNI 原则)。最有力的提案是用真实数据支撑,而非仅凭假设。

一份好提案应包含:

  • 简要摘要:动机与背景
  • 设计变更说明
  • 优缺点(Pros + Cons)
  • 前期投入工作量
  • CI/CD、发布、持续维护所需工作量
  • 迁移策略 / 向后兼容性
  • CLI 交互方式的界面草图或示例
  • 复现所针对问题的清晰示例

提案获得 design/approved 标签后即可开始 PR 工作。若是提议新工具或新服务,务必先做尽职调查:第三方是否已有可复用的实现?文档举例:定时/CRON 型函数调度是已被充分解决的问题,无需重复造轮子。不遵循流程的 PR 可能被关闭或标记为 invalid。

PR 文书工作清单

提交 PR 前必须通读整份指南并同意 DCO 协议,同时满足:

  1. 遵循下文 commit 消息规范
  2. 签署所有提交(git commit --signoff 或 -s)
  3. 完整填写 Issue 与 PR 模板
  4. 在 PR 描述与 commit 消息中引用被修复的 Issue(使用 "Fixes #IssueNo")
  5. 始终给出测试说明——尽可能提供 CLI 命令、输出或截图

Commit 消息规范

基于 Chris Beams 的 Git commit 指南,规则如下:

  • 使用 git commit --signoff 或 git commit -s 签署
  • subject(首行)以大写字母开头
  • subject 不超过 72 字符
  • subject 不以标点符号结尾
  • 注意:不要使用 GitHub 的 suggestions 功能,它无法让提交被 sign-off
  • 有 body 时:subject 后留空行,所有行折行到 72 字符

被接受的示例:

Add alexellis to the .DEREK.yml file

We need to add alexellis to the .DEREK.yml file for project maintainer
duties.

Signed-off-by: Alex Ellis <alex@openfaas.com>

两个反面示例及原因:

(feat) Add page about X to documentation

自定义 (feat) 前缀不符合约定

Update the documentation for page X so including fixing A, B, C and D and F.

过长的 subject 会在 GitHub UI 与 git log --oneline 中被截断

这一规范在仓库中有直接证据:根目录的 .DEREK.yml 记录了 curators(维护者)名单,并将 dco_check、comments、pr_description_required、release_notes 列为机器人启用的功能特性——DCO 检查与 PR 描述必填正是由 Derek 机器人在每个 PR 上自动把关的。

Go 单元测试风格与 goleak

OpenFaaS 的 Go 测试有明确的风格约束:使用原生 Go 代码断言结果,不引入 .NET/Java 风格的断言库(如 stretchr/testify)。文档给出的风格示例:

func TestSum(t *testing.T) {
    want := 10
    got := Sum(5, 5)
    if want != got {
       t.Fatal("want: %d, but got: %d, want, got)
    }
}

文档允许使用测试表(test tables)、额外的比较库或辅助函数,但明确不会被合并的写法是:

func TestSomething(t *testing.T) {
  assert := assert.New(t)

  // assert equality
  assert.Equal(Sum(5, 5), 10, "they should be equal")

这一风格在仓库测试中随处可见。例如 gateway/handlers/alerthandler_test.go 的 TestScaling_SameUpperLowerLimit 采用的就是 want := ...; if want != got { t.Fatalf(...) } 的原生断言模式。

关于 goroutine 泄漏:如果改动涉及 goroutine,请在测试最前面加入 goleak 检查:

defer goleak.VerifyNoLeaks(t)

测试结束时若检测到被打开却未清理的 goroutine,测试即失败。仓库中的 gateway/handlers/logs_test.go 与 gateway/handlers/logs_test.go 分别在"provider 关闭连接"与"客户端关闭连接"两个日志代理场景中使用了 defer goleak.VerifyNone(t);gateway/go.mod 中也正式声明了 go.uber.org/goleak v1.3.0 依赖,验证了该实践的真实落地。

添加依赖的规则

所有项目使用 Go modules 与 vendoring:每个仓库的 vendor 目录保存依赖源码副本,实现可重复构建与变更隔离(当前仓库的 gateway/vendor 目录即是证据,gateway/go.mod 显示 Go 版本为 1.24 且模块名为 github.com/openfaas/faas/gateway)。

组件许可证必须为 MIT、BSD 或 Apache 2.0。对于琐碎或已无人维护的依赖,维护者可能要求你自行编写代码。

提问、支持与期望管理

对于深入的技术问题或调试求助,应准备一个公开的、包含最小复现代码的简单 GitHub 仓库。

期望与 SLA

  • 免费用户的支持范围:仅修复代码库中的 Bug 与问题,前提是完整填写 Issue 模板并给出足够的复现说明;社区不会在 GitHub 上替你调试应用或评审架构。
  • Issue 的 SLA:由志愿者以尽力而为(best effort)的方式分类与答复,响应时间可能是 1 分钟、1 小时、1 天或 1 周,没有隐含的承诺。没有响应的 Issue 不代表不重要,只是尚未处理或可能被遗漏——请主动跟进。
  • PR 的 SLA:同样由 Core Team、Members Team 与 Project Lead 组成的志愿者团队分类评审,项目组件众多而人手有限,PR 可能被阻塞或需要进一步操作。
  • PR 可能被延迟的原因:未遵循贡献指南、提交未 sign-off(Derek 机器人会提示)、提交需要 rebase、有变更请求、或 PR 优先级/影响力较低;此外可能还需要更多信息、用例或上下文。
  • GitHub Sponsor:赞助者会在 Issues 和 PR 上显示 Sponsor 标识,这是支持社区与项目的一种方式。

版本发布机制

版本由 Project Lead 定期或在必要时发布。发布流程为:使用 git 标签切版本,一次成功的 CI 构建会将新的二进制产物与 Docker 镜像发布到镜像仓库(文档所述发布通道为 Docker Hub 与 Quay.io),凭据由 Project Lead 维护。当前仓库的 Makefile 也印证了构建方式:build-gateway 目标通过 docker buildx build --platform linux/amd64 构建 Gateway 镜像,generate 目标由 api-docs/spec.openapi.yml 生成 Go models。

治理结构与维护者体系

OpenFaaS 是 2016 年由 Alex Ellis 创立的独立开源项目,现由 OpenFaaS Ltd(公司编号 11076587)托管与赞助,维护工作由常规志愿者与更广泛的开发者社区完成。社区内存在四级结构:

  1. Core Team(GitHub org)
  2. Members Team(GitHub org)
  3. 拥有 Derek 访问权限者
  4. 更广泛的社区

Core Team

Core Team 直接与 Project Lead 沟通,负责战略、项目维护、社区管理,并承诺每周投入固定时间。每位成员通常负责 OpenFaaS 某个子系统的 SME(领域专家),并拥有相关仓库的写(push)权限。额外职责包括:每月至多一次与 Project Lead 的一对一 Zoom 会议、离开一周以上需通知并设置 Slack "away" 状态。文档列出的 Core Team 成员包括 Alex Ellis(创始人)、Han Verstraete、Lucas Roesler(日志/provider 模型/secrets 的 SME)、Nitishkumar Singh。

Members Team

Members Team 是社区中久经考验的贡献者,具备以下履历:修复、测试与分类 Issues/PR、为项目提供支持、反馈并随时待命、评审 PR、参与贡献者会议并帮助新贡献者。团队强调沟通是核心技能——无法定期沟通者可能不适合加入,但随时欢迎以更广泛社区身份贡献。

Members Team 通过项目机器人 [Derek] 获得不同程度的写访问权,帮助常规贡献者向 Members Team 过渡。其福利包括私有 Slack 频道、官网 Team 页面展示、GitHub 组织成员身份,以及按需提供的 1:1 教练/指导、演讲与 CfP 支持、简历与职业发展帮助、博客推广等。职责则包括参与成员频道讨论、参加社区 Zoom 会议、持续贡献代码、活跃于公开频道、评论功能提案等。

团队变动与 Emeritus 状态

每位贡献者(包括 Project Lead)都是志愿者,动机与生活状况会随时间变化:

  • 短期变化:与 Project Lead 沟通,可协商保留福利的 sabbatical 安排
  • Core Team 可转入 Members Team(需通知 Project Lead)
  • 无法继续团队承诺时,可转为 Community Contributor,只要仍有价值即可保留 Derek 访问权
  • 退出或脱离时,应以最小化项目干扰的方式:告知 Project Lead,并确保他人能接续你的工作

Derek 机器人访问

如果你被加入仓库根目录的 .DEREK.yml 文件,即可通过在 Issues 与 PR 上发布评论来协助管理社区。当前仓库的 .DEREK.yml 配置了六位 curators(alexellis、LucasRoesler、viveksyngh、nitishkumar71、rgee0、welteki)以及 dco_check、comments、pr_description_required、release_notes 四项功能,并指向本贡献指南作为 contributing_url。贡献者欢迎申请该访问权限。

品牌与媒体

关于媒体发布、品牌、Logo 与标识,参见 OpenFaaS 官方 media 仓库。

社区资源与 Roadmap

项目虽然用 Golang 编写,但许多社区贡献来自博客、演讲、测试与需求驱动的 backlog 推进。仓库内的 community.md 汇总了博客、演讲与包含示例函数和用法的代码仓库,包含历年(2017-2023)的博客、活动、演讲记录以及各类 provider 的状态清单(官方支持的 faas-netes、faasd,社区孵化中的 faas-nomad、faas-memory,已弃用的 faas-swarm 等)——如果你用 OpenFaaS 做了有趣的事情,欢迎通过 PR 提交到该页面(同样需要 git commit -s 签署)。

许可证与版权

双许可证结构

  • 所有第三方贡献以 MIT 许可证 授权
  • OpenFaaS Ltd 的贡献以 EULA.md(OpenFaaS CE EULA)授权
  • OpenFaaS Standard 与 OpenFaaS for Enterprises 为专有软件,二进制以 pro/EULA.md(商业 Pro EULA)授权

Copyright 声明

贡献者保留各自贡献的版权,但同意按 MIT 许可证授权项目使用;Git 保留作者历史,项目使用概括性声明而非个人署名。新增文件时请添加版权声明:

// Copyright (c) OpenFaaS Author(s) 2023. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

(仓库测试文件中的 // License: OpenFaaS Community Edition (CE) EULA 头注释即为此类声明的实例,参见 gateway/handlers/alerthandler_test.go。)

DCO:签署你的工作

PR 或补丁中的每个提交都必须签署。签名是补丁说明末尾的一行简单文本,证明你撰写了该补丁或有权利以开源补丁形式提交它,认证规则出自 Developer Certificate of Origin 1.1:

Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

之后在每个 git commit 消息中追加一行:

Signed-off-by: Joe Smith <joe.smith@email.com>

使用真实姓名(不接受化名或匿名贡献)。若已在 git config 中设置 user.name 与 user.email,可直接用 git commit -s 自动签署。忘记签署时可借助 git rebase 重写历史来补救。这与 GPG 数字签名不同——GPG 并非贡献本项目的必需条件。

结语

从第一份自我介绍到第一个被合并的 PR,再到成为 Members Team 一员,OpenFaaS 的贡献路径始终围绕"先沟通、再编码、签署每一笔提交"三个原则展开。文档中的每条规范都不是空话:.DEREK.yml 中的 dco_check 与 pr_description_required 自动校验你的提交与 PR 描述,gateway/handlers 下的测试文件则展示着原生断言与 goleak 的真实用法。按这份指南行动,你的贡献就能与这个 Golang Serverless 项目的既有节奏无缝衔接。

登录后查看全文
faas