Github 是如何使用 Github 来处理 Github 文档的
| 2015-01-12 14:54 评论: 2 分享: 3
提供书写良好的文档,可以帮助人们理解并很好地使用你的项目,而且人们还能够很容易地参与你的项目并作出贡献,但这仍不够。基于文档服务的底层系统能够使任何人——包括你或你的团队写文档更轻松。
对于文档的编写,最大的难点不是如何配置工具,或者要弄清楚怎么部署更新,而在于如何斟词酌句。GitHub文档制作团队的成员有着丰富的工作背景,包括使用原生的基于XML的写作工具,以及复杂的CMS系统。但我们并不想使用那些工具,因此我们花费了大量时间和精力来配置我们自己的文档制作流程和工作计划。
以前我们也谈论过怎么使用GitHub构建GitHub;如下就是我们怎样使用 GitHub Pages 每月向数百万读者提供 我们的GitHub帮助文档。
我们以前的流程
几个月前,我们把帮助系统的站点从自建的Rails程序迁移到了 Github Pages 上的Jekyll。之前我们的帮助系统需要两个相互独立的项目仓库:
-
负责运维网站、管理网站资源,以及实现文档搜索的 Rails 应用程序
-
由一大堆 Markdown 文件组成的网站具体内容
我们的 Rails 应用程序托管在一个第三方平台上。随着代码的不断更新升级,我们将它部署在了 Hubotand Chatops ,这些都是我们在维护 Github 主站的闲暇之余完成的。
我们正常的撰写流程可能是这个样子的:
-
当有新特征开发出来的时候文档团队首先编写好文档内容
-
创建一个新的 issue 去追踪这个特征
-
当文档更新完毕一切就绪之后,我们会发起一个 pull request 去迭代更新文档内容。
-
PR 发起成功后,我们会使用 @ 方式提醒团队(比如 @github/docs )并会让队友们审查一下我们的内容。
-
当这个特征开发完毕已经上线的时候,我们会合并之前创建的 PR。 使用webhook能够帮助我们在内容仓库快速激活我们部署的 Rails 应用程序。webhook 承担了负责更新数据库的任务。
下面是一个简单的示例,@neveretand@bernars给我们展示了一下我们正常的工作流程:
使用pull requests进行工作很有意思,因为它正好和我们团队使用的 Github工作流程是一致的。并且Markdown 的语法能让我们快速高效地表达出新特性的独到之处,所以我们写文档时,对它情有独钟。
然而,我们的 Rails 程序维护起来相当麻烦:
-
由于我们的主机是外部托管,所以我们需要工程,运维和安全团队的专业人员实时监控站点运行状况,并能及时处理突发事件。
-
我们的文档团队并不能方便的预览内容的变化。虽然我们使用 Markdown 编写内容,可以实时预览,但是我们仍然需要配置一个本地的 Rails 应用服务去运行脚本将内容导入到数据库中然后观察其在网站上的最终效果。
-
虽然我们不断的调整 Rails 服务器设置,而用户发起请求后响应速度依然缓慢。这是因为 HTML 页面是动态生成的,需要对数据库进行频繁访问,即便运用更为强大的缓存策略,依然收效甚微。
我们意识到,其实我们可以做得更好。
我们的新流程
当 Jekyll 2.0 发布的时候,我们意识到是时候使用静态网站了!特别是 Collections文档类型这个新特性使得定义自己的文件结构成为可能。不仅如此,Jekyll 2.0 还增加了 Sass 和 CoffeeScript 的支持,让前端代码的编写更简单。
开源的好处在于它是开放的。我们迁移到 Jekyll 后,我们也向 Jekyll项目发起了很多pull requests,贡献代码,使得它能更好的服务 Github Pages 的广大用户。
这时,我们的工作流程发生了小小的变化。但我们仍然使用 Markdown ,将写好的内容提交到仓库供他人审校。当我们的提交被合并之后,Github Pages 网站将会在几秒内自动快速创建并部署。
下面是我们就如何使用 Jekyll 的核心功能以及对 Github 帮助系统起增强效果的插件列了一个简单的纲要。
我们的法宝
我们主要依靠 Jekyll 核心代码的功能来完成任务,这样更省心省力,而不是将大量精力用于维护自定义插件。
Jekyll 2.0 提供的全新插件 Converter 可以将任何标记自动转换成 HTML。这样用户写文章就可以无拘无束,Jekyll 只负责运行最后生成的 HTML文件就好了。比如,你可以使用 AsciiDoc 语法发贴子。
最后,我们开发了 jekyll-html-pipeline 插件,是我们之前开源的 html-pipeline 在 Jekyll 上的增强版。这个确保了我们的帮助站点的内容在整个Github 上没有任何差异。同时我们也用自己开发的 Markdown filter 插件提供一些语法扩展,进一步降低了文档编写的难度。
搜索
在之前的Rails站点上,我们使用了ElasticSearch 提供商索引我们的数据库并为我们的帮助站点实现了搜索系统。
现在,我们使用lunr-js来提供更加快速的客户端搜索体验。通过我们的分析筛选,我们发现绝大多数的用户依赖于外部搜索服务提供商来获得我们的文档。在迁移期间或者迁移后,将大量的精力花在服务器端的搜索解决方案是没有什么意义的。
内容参考
文档团队希望在编写文档的时候使用“内容参考”。通过内容参考你可以写一大段文字然后在网站任何地方复用它。(这个想法借鉴于 the DITA standard)
旧的Rails应用并不能允许我们编写可复用的内容,但是现在我们借助于Jekyll data files 的力量。举个粒子,我么已经创建了一个叫做conrefs.yml 的文件,并且写了一系列键-值集合的字符串就像下面这样:
repositories: create_new: 1. In the upper-right corner of any page, click {{ octicon-plus Plus symbol }}, and then click **New repository**. ![New repository menu](/assets/images/help/repository/repo-create.png)
我们的键根据 (repositories.create_new )特异性进行分组;其对应的值为下面的Markdown源码( "In the upper-right corner...”)。使用使用合适的语法,我们只需要简单一步就能在不同页面引用创建一个新的仓库。
To start the process: {{ site.data.conrefs.repositories.create_new }} 2. Do something else. 3. You're done!
随着Github的界面变化,我们也许需要修改图片或者重新定义方向的指向。这样我们只需要借助内容参考,仅仅在改变一个地方而不是很多地方。
版本化的文档
另一个改变带来的好处是能够提供版本化的帮助文档。随着Github企业版2.0的发布,我们开始提供之前的11.10.340版本和现在的2.0版本这两个不同版本不同的帮助文档内容。为了实现这个,我们在Jekyll站点使用了特别的标志位audience,并在Pages仓库生成HTML时检查这个标志位。
例如,在我们的config.yml文件中,我们设置了一个叫做audience键其值为11.10.340。如果一个特性存在于企业版2.0而不在11.10.340,我们会使用如下语法标记上这一部分:
{% if site.audience != '11.10.340' %} This new feature... {% endif %}
以上的实现仅仅利用了Jekyll的核心功能,我们并不需要为此创建或者维护任何其他的东西。
测试我们的站点
并不是因为站点是静态的我们就可以避免开发测试驱动。
我们第一个测试内容工具一直是 html-proofer。这个工具通过快速得检验我们站点上的每个URL帮助我们核实我们的链接和图片是否正常。
Ruby使用者更加熟悉使用Capybara在他们的测试中模拟网站互动。在我们的静态站点中实现一个类似的工具,这个想法疯狂吗?不!我们的工程师@bkeepers 四年前写了一篇博客讨论了这个问题。这样,我们有能力进行一次更强有力的测试,这测试涵盖我们的内容已和网站行为。比如,我们通过检查YAML文件中的键是否存在确认某个内容是否有效,或者我们会检测javascript代码是否运行良好。
我们的帮助文档运行在CI上以确保用户不会拿到损坏的内容:
速度快
如上所述,比起原来的Rails应用,我们的新Pages实现在速度上有极大的提升。部分原因在于,网站内容主要是大量的静态HTML文件——无需访问数据库。但最重要的是, 我们花费了大量时间来优化Pages服务器使得访问速度狂飙 。另外,包括提供CDN这样的服务条件,我们也能一一满足。
让Github Pages为你工作
Github上的文档团队可以利用Github工作流,Jekyll 2.0和Github Pages来创建高质量的文档。Github Pages 提供给我们的文档团队的好处同样适用于任何使用Github Pages的用户。
随着我们将文档迁移到Pages,我们再也不需要重建任何新的组件。我们花了很少时间创建一些东西并花了很多时间讨论怎样的工作流对我们团队和公司才有意义。通过使用和广大Github用户一样托管系统,我们能提供更好更快的文档系统。我们内部的工作流使我们的工作效率显著提高,并且提供一些我们以前从未提供过的功能比如说版本化的文档。
如果你对我们的流程有任何疑问,无论何时,我们都很乐意帮助大家。