Kubernetes 指导委员会选举提名模板(nomination-template.md)结构与自动化校验实战
2026/9/16 20:15:27 网站建设 项目流程

Kubernetes 指导委员会选举提名模板(nomination-template.md)结构与自动化校验实战

【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community

本篇以 Kubernetes 社区仓库(community)中 2023 年 Steering Committee 选举使用的提名模板 nomination-template.md 为主体,完整拆解模板的 YAML 头部、命名规则与四个固定章节,并结合仓库内置的自动化校验工具 verify-steering-election-tool.go 的源码,说明一份候选人简介(bio)文件在合并前会被机器检查哪些规则、常见格式错误如何触发校验失败,以及 2023 年真实候选人文件长什么样。读完本文,你可以独立写出一份能直接通过 CI 校验、符合选举流程要求的提名文件。

一、这个模板是什么:Steering 选举中的角色定位

Kubernetes 指导委员会(Steering Committee)选举按年度在elections/steering/目录下按年份归档,elections/steering/README.md 说明该目录“包含 2017 年以来的所有 Kubernetes Steering 选举资料”,并以当年目录作为选举的唯一事实来源(single source of truth)。

模板文件本身只承担一件事:为候选人简介提供统一格式,让所有候选人的信息可以被一致地展示(渲染到 Elekto 选举应用中)和被机器自动校验。它由三部分构成:

  1. 以 61 个短横线围成的 YAML 头部:候选人元数据(姓名、GitHub ID、雇主、Slack);
  2. 四个固定的 H2 章节:SIGs、What I have done、What I'll do、Resources About Me;
  3. 一条 HTML 注释:提醒使用者“把本模板复制为candidate-githubid.md并保存到选举目录”。

模板原文全文如下(来自 nomination-template.md)):

------------------------------------------------------------- name: ID: GitHubID info: - employer: Your Employer or "Independent" - slack: slack handle ------------------------------------------------------------- <!-- Please make a copy of this template as "candidate-githubid.md" and save it to the election directory --> ## SIGS - SIGS/WG/UGs you're a member of ## What I have done ## What I'll do ## Resources About Me - Links to KubeCon or other conference talks or other related material - Links to social media

2023 年的选举背景与流程细节(提名、背书、投票、时间表、选举官名单)完整记录在同目录的 README.md 中,模板的使用必须放在这套流程里理解——下一节先把流程走一遍,再回到模板字段逐条讲。

二、提名流程:模板文件在整个选举中的位置

根据 2023 选举 README 的Candidacy Process,一名候选人从提名到公示简介要经过五步,模板出现在最后一步:

  1. 创建提名 issue:在 community 仓库创建 issue,标题格式为Steering Committee Nomination: Your Name (@yourgithub);他人提名需事先征得本人同意。
  2. 邮件通知:向 dev@kubernetes.io 发送邮件,主题与 issue 标题一致,正文附上 issue 链接并邀请有投票资格的人到 issue 下 +1(邮件里的 +1 不计入资格)。
  3. 接受提名:被提名人在提名issue(不是邮件)下回复类似 "I accept the nomination"。
  4. 用 PR 关闭 issue:候选人提交添加简介的 Pull Request,PR 正文必须包含Fixes #NNN(NNN 为提名 issue 编号),合并后自动关闭 issue。
  5. 按模板编写简介文件:复制该目录下的nomination-template.md,新建一个名为candidate-githubid.md的文件,填完所有字段,且不要做任何格式改动(avoid making any format changes)。

其余关键规则:

  • 字数:全部正文(biographical statements)建议总计约300 词,过长会被要求删减后才能合并。
  • 背书:需获得 3 名来自 3 个不同雇主的合格选民的背书(endorsement),本人若具备投票资格可算一人;只有 GitHub issue 下的背书有效,提名邮件下的无效。
  • 截止时间:提名(8 月 26 日)与简介(8 月 27 日)的截止均按AoE(Anywhere on Earth,UTC-12)当日结束计,2023 年时间表完整列于 README.md 的 Schedule 小节。
  • 逾期处理:候选人错过截止时间的情况由选举委员会逐案裁定资格。

目录的 OWNERS 文件把 approvers 配置为选举委员会committee-steering与三位选举官(kaslin、bridgetkromhout、dims),意味着简介 PR 正是由这组人在代码评审层面把关格式。

三、模板逐段拆解:字段、格式与取值

3.1 YAML 头部:61 个短横线的“定界符”

头部由上下两条分隔线围住,每条分隔线是恰好 61 个-字符

------------------------------------------------------------- name: ID: GitHubID info: - employer: Your Employer or "Independent" - slack: slack handle -------------------------------------------------------------

各字段含义与填写要求:

字段说明填写示例
name候选人真实姓名Arnaud Meukam
ID候选人的 GitHub ID,必须与文件名中的用户名完全一致ameukam
info结构化联系信息,YAML 列表形式,每项为单键映射见下
info[].employer雇主名称;独立贡献者填"Independent"VMware
info[].slack候选人在社区 Slack 中的 handleArnaud

info采用- employer: xxx这种“列表内含单键映射”的写法,是 Elekto 应用的既有约定。校验源码 verify-steering-election-tool.go 中有一条 TODO 注释说明了来龙去脉:

// TODO: Have Elekto accept both mapping and sequence forms for candidate info // so compatibility is enforced at the application boundary as well as here.

对应地,InfoData的自定义UnmarshalYAML同时接受mappingsequence两种写法(L57-L82),把 sequence 形式拍平为map[string]string——因此映射形式info:\n employer: X也能通过仓库侧校验,但模板默认、且与 2023 年所有真实候选人文件一致的形式是 sequence 形式。

为什么是 61 个短横线?校验工具用一个正则来提取头部(L36):

var yamlHeaderRegex = regexp.MustCompile(`(?s)^-{61}\s*\n(.*?)\n-{61}\s*\n`)

分隔线必须是文件开头的恰好 61 个-(行尾可带空格,L347-L355 的extractYAMLHeader注释明确写道 “The format requires exactly 61 dashes for consistency”)。测试用例 verify-steering-election-tool_test.go 专门验证了 60 个短横线的输入会失败(wantErr: true)。结论:复制模板时分隔线一个字符都不能增删改。

3.2 文件名规则:candidate-githubid.md

  • 文件名必须匹配正则^candidate-([a-zA-Z0-9_-]+)\.md$(L245-L248),即candidate-前缀 + GitHub 用户名 +.md后缀,仅允许字母、数字、下划线、短横线。
  • 文件名中的用户名必须与头部ID字段逐字符相等(L271-L284),不一致时报告filename username '...' does not match GitHub ID '...' in header
  • 因此命名是机械操作:GitHub ID 为justaugustus的人,文件就是candidate-justaugustus.md——2023 年目录下 11 个候选人文件(如 candidate-justaugustus.md、candidate-ameukam.md)全部符合这一规则。

3.3 四个固定章节及其写法要求

正文必须包含以下四个 H2 章节(顺序与模板一致,不要改动标题):

  1. ## SIGS:列出所参与的 SIG/WG/UG 及其中角色。校验工具对标题大小写宽容——## SIGS## SIGs均视为通过(L323-L342),但其余三个章节标题必须精确匹配。
  2. ## What I have done:过往贡献(角色、推动的项目、基础设施/发布经历等)。
  3. ## What I'll do:当选后的计划。选举章程要求候选人以“brand free”(去公司标签)的个人身份参选,基于对社区的贡献而非公司职位来陈述,README 的Campaigning小节对此有明确约束。
  4. ## Resources About Me:KubeCon 或其他会议的演讲链接、相关作品与社交媒体链接。

章节内内容可选(Biography statements are optional),但章节标题本身是必填项:缺任何一节都会被工具以missing required section: ...报错。

3.4 字数上限:450 是硬限,300 是建议线

工具定义了两个常量(L30-L34):

const ( maxWordCount = 450 recommendedWordCount = 300 startYear = 2026 )
  • 正文超过450 词直接判定为无效文件;失败输出会提示 “Bios should be limited to around 300 words, excluding headers.”
  • 统计方式值得注意:计数前先用yamlHeaderRegex把整个 YAML 头部剔除(L217-L236),再按空白符切分计数。也就是说头部元数据不占字数,但正文里的 Markdown 标记(如列表符-、链接里的文字)都会计入单词。测试用例 TestCountWords 覆盖了换行、多空格、纯空白、含头部剔除等边界场景。

四、对照实例:2023 年真实候选人文件如何填模板

以 candidate-ameukam.md 为例,可以看到模板填写后的完整形态:

------------------------------------------------------------- name: Arnaud Meukam ID: ameukam info: - employer: VMware - slack: Arnaud ------------------------------------------------------------- ## SIGS - SIG K8s Infra: SIG Chair - SIG Release: Release Manager Associate - SIG Testing ## What I have done I have been involved with the Kubernetes project since 2018. ... - Boostrap registry.k8s.io as the new distribution platform for our container images ... ## What I'll do As a member of the community, I am committed to pushing the project's progress ... ## Resources About Me - Twitter: [@ameukam](https://twitter.com/ameukam) - Talks: - Why We Moved the Kubernetes Image Registry ...

对照模板可以核对三个要点:

  • 头部字段全部填实:name写全名、ID与文件名candidate-ameukam.md中的ameukam一致、info保留 sequence 形式并填了employerslack
  • 四个章节标题原样保留,## SIGS中用列表写明所参与的 SIG 与担任的角色;
  • 正文是“贡献事实 + 施政主张 + 外部链接”的结构,未新增任何模板之外的章节。

其余 2023 年候选人文件(candidate-pacoxu.md、candidate-pohly.md、candidate-vincepri.md 等)均可作为风格与篇幅参照。

五、自动化校验:verify-steering-election-tool 的完整检查链

模板格式不只是靠人工评审保证的。仓库提供了命令行工具,verify-steering-election.sh 是入口脚本:

# hack/verify-steering-election.sh cd "$(dirname "${BASH_SOURCE[0]}")/.." go run hack/verify-steering-election-tool.go elections

它从仓库根目录运行 Go 工具并扫描elections目录。工具的主流程(main)对每个检出的 bio 文件依次执行四类检查:

  1. 字数检查countWords:剔除 YAML 头部后统计单词数,超过 450 即报错has N words
  2. 文件名与 GitHub ID 一致性validateFileNameAndGitHubID:文件名必须符合candidate-username.md,且与头部ID相等(L238-L287)。
  3. 模板合规性validateTemplateCompliance(L289-L345):
    • 头部必须可解析且nameID非空;
    • info中必须包含选举配置要求公示的全部字段——工具从同目录的election.yaml读取show_candidate_fields(L156-L169),逐个检查info.<field>非空,缺失时报missing required field: info.slack这类错误;
    • 四个必需章节标题必须存在。
  4. 年份过滤findBioFiles:只校验路径含/2026/至“当前年份+5”范围内目录中的candidate-*.md文件(L171-L215)。

任何一项失败,工具会逐条打印文件: 原因,最后输出N invalid Steering Committee election bio(s) detected.并以退出码 1 结束,阻断 PR 合并。对应的单元测试 verify-steering-election-tool_test.go 对每个函数都写了正反用例,包括:61 vs 60 个短横线、mapping vs sequence 形式的info、文件名不匹配、缺name/ID/info.slack、缺 SIGs 章节、## SIGs大小写变体、以及年份窗口(2025 年的文件不校验、2026 年起校验、超出 5 年的未来年份不校验)。

常见校验失败与原因速查

错误信息(节选)触发原因修复方式
filename must follow format 'candidate-username.md'文件名不是candidate-前缀加合法用户名,或扩展名不是.md按 GitHub ID 重命名文件
filename username 'x' does not match GitHub ID 'y' in header文件名与头部ID不一致使二者逐字符相同
could not find YAML header between dashes分隔线不是恰好 61 个-,或未位于文件开头原样复制模板分隔线,勿改动
info must be a mapping or sequenceinfo写成了标量(如info: xxx恢复列表/映射形式
missing required field: name / ID / info.employer / info.slack头部字段缺失或为空按模板逐字段填实
missing required section: What I'll do缺少固定章节标题保留模板中的四个 H2 标题
has 480 words正文超过 450 词压缩到约 300 词(头部不计入)

六、与选举配置的联动:election.yaml 如何驱动校验

2023 年选举的配置 election.yaml 同时服务于 Elekto 应用和上述校验工具,关键字段:

name: 2023 Steering Committee Election organization: Kubernetes start_datetime: 2023-08-29 00:00:01 end_datetime: 2023-09-27 11:59:59 no_winners: 4 allow_no_opinion: True delete_after: True show_candidate_fields: - employer - slack election_officers: - dims - kaslin - bridgetkromhout eligibility: Kubernetes Org members with 50 or more contributions in the last year can vote. ... exception_description: Not all contributions are measured by DevStats. ... exception_due: 2023-09-24 11:59:59

要点:

  • no_winners: 4对应 2023 年选出 4 名任期两年的委员;election_desc.md 说明了该季度另有 3 名现任成员(@BenTheElder、@mrbobbytables、@palnabarun)继续履职。
  • show_candidate_fields声明employerslack两字段,这正是校验工具强制候选人info中必须非空的两项(见 TestValidateTemplateCompliance 中candidateFields := []string{"employer", "slack"}),也是选举应用向公众展示候选人身份的来源。
  • election_officers(dims、kaslin、bridgetkromhout)与 OWNERS 的 approvers 及 README 中列出的选举官名单(Kaslin Fields、Davanum Srinivas、Bridget Kromhout)互相印证,三位选举官同时是简介 PR 的审批人。
  • 投票规则方面,2023 年采用限时 Condorcet 排序投票(允许 "no opinion",与allow_no_opinion: True对应),平票由无利益关联的 SC 成员掷硬币决定,均见 README.md 的 Voting Process 小节。

需要说明的适用前提:校验工具当前只对 2026 年及以后的选举目录强制执行(startYear = 2026),2023 年目录中的文件是通过人工评审保障格式的;但 2023 年全部候选人文件事实上都满足工具所检查的每一条规则,可作为格式基准。

七、可复用的操作清单

结合模板原文、2023 年 README 流程与校验工具规则,写一份合规提名简介的操作清单如下:

  1. 复制 nomination-template.md 为candidate-<你的GitHubID>.md,放入当年选举目录;
  2. 保持两条 61 短横线的分隔线原样不动,填实name(全名)、ID(GitHub ID,与文件名一致)、infoemployer(公司或"Independent")与slack(Slack handle),保留- key: value的列表形式;
  3. 依次填写四个章节,标题保持## SIGS## What I have done## What I'll do## Resources About Me不变;
  4. 控制正文总字数在 300 词左右(硬上限 450 词,头部不计入);
  5. 在提名 issue 上确认已获得 3 名来自 3 个不同雇主的合格选民背书;
  6. 提交 PR,正文写Fixes #<提名issue编号>,由选举官/委员会(见目录 OWNERS)评审合并;
  7. 提交前可自行对照第五节的“常见校验失败速查”表逐项自查,或本地执行 hack/verify-steering-election.sh 中go run hack/verify-steering-election-tool.go elections的同款逻辑核对格式。

掌握以上内容后,提名模板不再是“照抄填空”的动作,而是一套可预测、可自查、可通过自动化校验的格式契约:文件名 ↔ID字段 ↔ 61 短横线头部 ↔show_candidate_fields字段 ↔ 四个固定章节 ↔ 450 词上限,任何一环不满足都会被 verify-steering-election-tool.go 明确点名。

【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询