我几乎是偶然发现了 Google 文档季(GSoD),这要归功于我对 HackerNews 和 Twitter 的沉迷。我熟悉 Google Summer of Code(GSoC),但对这个项目并不熟悉。事实证明这是首个阶段。我阅读了细节,整个过程感觉很像 GSoC,只是这次是关于文档的。
关于我
过去一年半,我一直在 Medium 和我的博客上撰写技术文章。写博客帮助我检验对概念的理解,因为把最困难的想法用简洁的句子表达出来需要相当多的时间投入。
另外,我过去三年一直从事软件开发工作,这也包括为我的项目编写文档。我在 IIT Roorkee 完成了工学学士学位。在大学期间,我曾申请过一次 GSoC,但未进入最终的入选名单。
我把 GSoD 视为一个利用开源社区反馈提升技术写作能力的绝佳机会。我曾为 Apache Superset 和 Apache Druid 贡献过一些 bug 修复和功能,但这将是我第一次以技术写作者的身份贡献。
寻找组织
GSoD 有 40 多个组织参与。然而,有两个组织第一眼就对我来说是最合适的。第一个是 Apache Airflow,因为我已经广泛使用过 Airflow,并且在前公司分叉的版本中贡献过一些自定义算子。
第二个是 Apache Cassandra,我也对其有大量使用经验,但没有做过代码或文档的修改。
综合考虑我的经验,我决定选择 Airflow。
项目选择
在确定组织后,下一步是选择项目。同样,我的前期经验在此起了作用,最终我选中了 如何创建工作流。该项目的目标是编写文档,帮助用户创建复杂以及自定义的 DAG。不过最终的交付物略有不同,后面会详细说明。
提交申请后,我继续忙于工作,直到有一天,我收到了 Google 的邮件,确认我被选为该项目的技术写作者。
社区融合
被选中只是一个开始。我收到了 Airflow Slack 频道的邀请,那里进行大部分讨论。我的导师是来自 Apache Airflow 的 Ash-Berlin Taylor。我开始与导师沟通,以大致了解预期的交付物。这些交付物记录在 confluence 中。
- 一个关于如何创建 DAG 的页面,还包括
- 改进与调度 DAG 相关的页面
- 添加针对特定 DAG 情况的提示,例如重新运行失败的任务
- 一个关于开发自定义算子的页面,包括
- 描述在创建算子时重要的机制,如模板字段、UI 颜色、hooks、连接等。
- 阐述算子与 hook 之间的职责划分
- 处理共享资源(如连接和 hooks)时的注意事项
- 一个描述如何定义任务之间关系的页面。该页面应包含以下信息:
- ** >> << **
- set upstream / set downstream
- helper 方法,例如 chain
- 一个描述任务间通信的页面,还包括
- 改进与 macros 和 XCOM 相关的页面
我的导师很早就说明,交付物更像是指南而非硬性规则。如果我愿意,也可以选择做与项目相关的其他工作,哪怕不在交付清单中。与导师沟通后,我开始参与整个 Airflow 社区。社区里的成员都非常乐于帮助,尤其是 Kamil Bregula。Kamil 帮助我了解在为 Airflow 编写文档时需要遵循的指南。
文档开发
我选择 DAG run 作为我的第一个交付物。我之所以选这个主题,是因为其部分内容已经有文档,但需要补充文字。我把现有的 Scheduling & Triggers 页面拆分为两个新页面。
- 调度器
- DAG 运行
与调度器无关的大部分细节被移动到 DAG 运行页面,然后补上了如如何重新运行任务或 DAG 等缺失的内容。当我对自己的版本满意后,邀请了导师和 Kamil 进行审阅。第一版我把文本放在 Google Docs 文件中,审阅者在其中添加了评论。但文档逐渐变得杂乱,难以追踪改动。于是我决定正式提交 Pull Request。
这正是我遭遇的第一个挑战。Apache Airflow 的文档使用 RST(reStructuredText)语法编写,而我对其完全陌生,之前大多使用 Markdown。随后几天我花时间学习该语法,幸运的是上手相对容易。我提交了 Pull Request 并等待评论。几天后看到评论,主要集中在两方面——语法和排版,还有一些我遗漏或误解的地方。
使用正确的语法
在与 Kamil 讨论后,我决定遵循 Google 开发者文档指南。该指南几乎涵盖了撰写优秀文档时需要考虑的所有要点,例如始终使用主动语态。随后,我装了 Grammarly 插件。每次写完文档后,我都会把内容放进 Grammarly 检查错误,修正后再次提交,如此循环,直到文档在语法上完全正确且看起来不像是由 AI 生成的。
排版
排版涉及编写提示和注意事项、在文本中准确标记 Airflow 组件,并确保快速浏览文档的用户不会错过关键信息。这需要一些反复试验。我研究了 Airflow 文档当前的排版模式,做出修改、提交代码、整合新的审阅意见……循环往复。
最终,所有审阅者都批准了 PR,但它直到两个月后才被合并。原因是我们怀疑还有其他页面(例如 Concepts)是否也需要拆分,从而得到结构更清晰的文档。最后我们决定延后合并,等与更广泛的社区讨论后再行动。
我的 第二个 PR 完全是一篇新文档,主题是 如何创建自定义算子。此时我已经熟悉了大部分语法,直接在不经过 Google Docs 的情况下提交了 PR。再次收到了大量评论,这次更多是针对我写的内容本身,而不是写法本身,例如详细说明如何使用 template fields 并清理代码示例。较少的语法与排版错误评论说明我已经取得进步。该 PR 在两周内被接受,极大提升了我的自信。
第二个 PR 通过后,我陷入了一点僵局。最后剩下的交付物与 Macros 相关,但范围并不明确。我与导师沟通,他表示如果我想暂时转向其他工作也没关系,等社区弄清楚需要哪些改动再回来。我们讨论了很多想法,最终我决定参考导师在一次 meetup 上关于 Apache Airflow 的演讲,撰写一份最佳实践指南。由于我自己在生产环境运行 Airflow 时也遇到不少挑战,我非常有动力写出这样的文档以帮助其他开发者免于遭受相同困扰。两周内完成了首稿,我起名为 Running Airflow in Production。但在补充几段内容后,我意识到更合适的名称应是 Best Practices 指南,这也是大多数开源项目所采用的形式。
社区对这个 Pull Request 反响热烈,因为很多人都遇到了文档中描述的那些挑战。我正中要害。经过 1‑2 周的讨论后,我的 PR 最终获批。
随后我回到第一个 PR,依据新的审阅意见进行了一些修改。之后,我与导师讨论了他关心的细节,例如如何用尽可能简洁的语言让用户理解 schedule interval 的工作原理。经过多次反复试验,我们终于得到一个双方都满意的版本。
最终评估
9 月 12 日,我收到了 Google 发来的邮件,确认项目已成功完成。这意味着我的导师认可了我的工作,Airflow 社区也对我的贡献表示赞赏。
我的文档最终发布在 Airflow 官网 -
我也开始受邀参与其他开发者的 PR 审核。期待在来年对项目做出更多贡献。
分享