Elsa Workflows 贡献指南:Trunk Based 开发流程、PR 规范与 ADR 记录实践
Elsa Workflows 贡献指南:Trunk Based 开发流程、PR 规范与 ADR 记录实践
本文以 Elsa Workflows 官方贡献规范(CONTRIBUTING.md)为主线,系统讲解该 .NET 工作流引擎仓库的开发工作流、Pull Request 提交标准、Bug 报告要素、功能请求的优先级机制,以及独具特色的"日期命名 + 自动生成索引"架构决策记录(ADR)流程。读完本文,你将掌握向 Elsa 提交高质量 PR 的完整操作路径,理解 doc/adr/ 目录与 scripts/adr/generate-toc.sh 脚本的运行机制,并能按仓库实际规范写出符合审核预期的问题单与特性提案。
一、开发工作流:Trunk Based Development
Elsa 采用 Trunk Based Development(主干开发),所有变更都必须通过 Pull Request 合入 main 分支,禁止绕过 PR 直接向主干提交代码。官方推荐的提交流程为五步:
- Fork 仓库,并从
main分支创建自己的开发分支; - 如果新增了需要测试的代码,补充对应的测试;
- 如果改动涉及 API,同步更新文档;
- 确保整个测试套件通过;
- 向
main分支发起 Pull Request。
这一流程与仓库的实际工程结构是配套的:源码位于 src/(含 Elsa.Workflows.Core、Elsa.Workflows.Runtime 等 512 个文件的模块,以及 src/apps/ 下的宿主应用),测试分散在 test/unit/、test/component/、test/integration/ 三个层级,例如 test/unit/Elsa.Workflows.Core.UnitTests 存放核心单元测试、test/integration/Elsa.Workflows.IntegrationTests 存放端到端集成测试。新增逻辑时对照相应层级补测,是代码能被合入的前提之一。
架构决策记录(ADR)的独特约定
Elsa 的架构决策记录集中存放在 doc/adr/ 目录,贡献规范对其有一套非常明确的约束:
- 新 ADR 命名:必须采用
YYYY-MM-DD-slug.md格式(如2026-09-15-correlated-workflow-activation.md),文件内使用#一级标题书写标题,标题本身不带任何数字前缀; - 历史记录不动:旧式的
NNNN-编号记录(如 doc/adr/0001-record-architecture-decisions.md)保持原名、原标题、原链接,禁止重编号、禁止续编序列; - 索引自动生成:doc/adr/toc.md 是生成文件,新增或改标题后必须运行
scripts/adr/generate-toc.sh并提交结果,CI 会通过--check模式校验,索引过期即视为 PR 不通过。
为什么放弃顺序编号?
这一约定源自一次真实的历史教训,详见 doc/adr/2026-08-25-date-prefixed-adr-identifiers.md:旧方案按顺序编号,但编号过程没有任何预留(reservation)机制,多个并行分支往往同时选中同一个数字。User Tasks 相关记录曾在两次 main 合并中连续被重编号两次(0011/0012 → 0014/0015 → 0026/0027),每次重编号都要重命名文件、修改文件内 # NN. 标题、手工重建 toc.md 并复查失效链接,而这些工作与决策内容毫无关系。改用日期命名后,同一天新增两条 ADR 也不会冲突;即便冲突,只需重命名其中一个文件,而不是连锁重编号。
generate-toc.sh 脚本工作机制
scripts/adr/generate-toc.sh 是纯 bash 脚本(set -euo pipefail),其核心逻辑可直接从源码解读:
- 标题来源:通过
grep -m 1 '^# '提取每个 ADR 文件的#一级标题作为索引标题,并剥离旧式的NN.数字前缀,保证标题永远来自文档本身而非人工记忆; - 分类排序:脚本先用 glob 匹配
toc.md跳过自身,再按命名约定分流——YYYY-MM-DD-*.md归入 dated 组、NNNN-*.md归入 numbered 组,其余命名一律报错退出。输出时 numbered 记录在前、dated 记录在后(每条 dated 记录必然晚于所有 numbered 记录,平铺列表即可保持时间顺序); - 细节处理:编号用
10#前缀强制十进制解析,避免零填充编号被误读为八进制;dated 记录取文件名的前 10 个字符(即YYYY-MM-DD)作为序号; - 两种模式:
./scripts/adr/generate-toc.sh—— 直接重写 doc/adr/toc.md;./scripts/adr/generate-toc.sh --check—— 只校验不写入,索引过期时以diff输出差异并返回退出码 1。
CI 侧则由 .github/workflows/adr-toc.yml 承担:该工作流在 pull_request 事件中监听 doc/adr/**、scripts/adr/** 及工作流自身的变化,在 ubuntu-latest 上运行 ./scripts/adr/generate-toc.sh --check,索引过期直接判定 PR 失败。这正是规范中所说"索引永不手工编辑"的机器保障。
二、Pull Request 规范:让审查更快、更安全
Elsa 对 PR 的总体期望是:易于审查、易于推理、安全合入。规范给出了三条硬性准则。
1) 一个 PR 只解决一个关注点
PR 应保持单一逻辑变更:
- ✅ 允许:Bug 修复、纯重构(无行为变化)、格式化、依赖升级、文档变更;
- ❌ 禁止:把无关的清理工作与功能改动混在一起。
原因很直接:混合关注点会增加审查者的认知负担、拖慢审查速度、提高合入风险。如果你在修 Bug 时顺手发现了可清理的代码,规范建议:
- 优先用标题为
refactor: ...或chore: ...的后续 PR 承接; - 或者把清理严格限制在该次修复所必需的范围内。
混合无关改动的 PR 可能会被要求先拆分再继续审查。
2) 让审查变快
一个合格的 PR 描述应包含:
- 清晰的问题陈述(problem statement);
- 预期行为(expected behavior);
- 可复现步骤(如适用);
- 验证步骤(steps to verify);
- UI 变更的截图或视频(如适用)。
仓库的 .github/pull_request_template.md 正是围绕这些要素设计的标准模板。PR 越容易审查,合入就越快。
3) 优先小 PR
小 PR 的优势是:更易审查、合入风险更低、更容易获得及时反馈。如果改动很大,请考虑拆分成多个增量 PR 依次提交。
三、报告 Bug:信息完备是快速解决的前提
Bug 与功能请求统一通过 GitHub Issues 跟踪。规范要求 Bug 报告至少包含:清晰摘要、复现步骤、预期行为、实际行为、相关日志或截图、示例代码(如适用)。仓库还提供了一份高度结构化的 Bug 模板 .github/ISSUE_TEMPLATE/bug_report.md,将上述要素细化为可直接填写的字段:
- 描述:对 Bug 的简洁清晰说明,含错误信息或错误码;
- 复现步骤:逐条给出步骤,尽量具体,并附代码片段;如果 Bug 可通过特定工作流复现,请附带工作流的 JSON 文件(Elsa 的工作流定义以 JSON 序列化,附文件可让维护者精确定位问题);条件允许时提供可复现的最小示例项目;
- 复现频率:说明是"每次必现"还是"约 50% 概率"等间歇性表现;
- 视频/截图:复杂行为建议用视频或截图辅助说明;
- 附加配置:复现所需的具体设置、特性开关或配置项;
- 预期/实际行为:分别描述应当发生与实际发生的结果;
- 环境信息:Elsa 包版本(若已克隆仓库则说明是否基于
main分支最新源码)、操作系统版本、浏览器及版本; - 日志输出:任何有助于诊断的日志或错误输出;
- 排查尝试:你自己已经尝试过的处理步骤;
- 附加上下文与相关问题:其他背景信息及关联 Issue。
规范特别强调:详尽的 Bug 报告能显著提高快速、准确解决问题的概率。对于 Elsa 这种依赖"工作流 JSON + 宿主环境"才能定位问题的引擎类项目,Workflow JSON 附件往往比任何文字描述都更能加速诊断。
四、功能请求与优先级:没有承诺的时间线
Elsa Workflows 是开源项目,并非所有功能请求都能立即或按需实现。功能开发的优先级由以下五类因素综合决定:
- 项目愿景与路线图:与 Elsa 长期方向契合的功能优先;仓库根目录的 ROADMAP.md 和 doc/adr/ 中的决策记录即是愿景的落地载体;
- 真实世界需求:有具体用例背书、尤其是生产环境中验证过的功能更可能被优先实现。如果你的场景迫切需要某功能,说明你的使用规划会非常有帮助;
- 社区贡献:社区提交设计或 PR 能显著加速推进,维护者乐于协作并审查贡献;
- 维护者时间与带宽:Elsa 在积极维护,但开发产能有限,部分功能需要时间;
- 赞助/付费工作:有明确时间线诉求的组织可通过商业支持获得专属开发时间。
在实践中意味着什么
- 功能请求没有承诺的时间线;
- 部分功能会保持开放,直到上述因素发生变化;
- 推动功能落地的最佳方式是:提交提案或实现、提供有力的真实用例、或赞助/资助该项工作。
所有功能请求与反馈都会被认真对待,它们是塑造 Elsa Workflows 发展方向的重要输入。
五、License 约定
通过提交贡献,即表示你同意你的贡献将依据项目的 MIT License 授权。许可证全文见仓库根目录 LICENSE,这也是本仓库对外分发与再使用的法律基础。
小结:一份合规贡献的操作清单
综合全文,向 Elsa 提交一次高质量贡献的落地路径是:
- 从
main创建分支,保持单一关注点,小步提交; - 按 test/ 目录对应层级补充测试,改动 API 时同步更新文档;
- 本地跑通测试套件后发起 PR,按 .github/pull_request_template.md 写清问题陈述、预期/实际行为与验证步骤;
- 若涉及架构决策:在 doc/adr/ 新增
YYYY-MM-DD-slug.md(标题不带数字前缀),运行scripts/adr/generate-toc.sh重新生成索引并提交,确保.github/workflows/adr-toc.yml的 CI 检查通过; - 报 Bug 时按 .github/ISSUE_TEMPLATE/bug_report.md 完整填写,工作流问题务必附带 Workflow JSON。
遵循这套规范,你的贡献将更容易获得快速、准确的审查与合入。